Skip to content

fix: -32602 state-unavailable errors no longer classified deterministic - #12

Merged
maoueh merged 1 commit into
developfrom
feature/fix-wrong-determinstic-state-not-found-error
Jul 14, 2026
Merged

fix: -32602 state-unavailable errors no longer classified deterministic#12
maoueh merged 1 commit into
developfrom
feature/fix-wrong-determinstic-state-not-found-error

Conversation

@maoueh

@maoueh maoueh commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Problem

rpc.IsGenericDeterministicError trusted the JSON-RPC error code alone: any -32602 (JSON_RPC_INVALID_ARGUMENT_ERROR) or -32600 (JSON_RPC_INVALID_REQUEST_ERROR) was classified deterministic.

Some nodes reuse -32602 for state/block unavailability (pruned node). This is transient and node-capability dependent — an archive node, or the same node at a different time, answers the exact same call correctly. Downstream consumers (e.g. evmx) cache deterministic errors permanently, so such an error poisons the (block, to, data) cache key forever.

Exact error observed in production on Monad RPC:

rpc error (code -32602): Block requested not found. Request might be querying historical state that is not available. If possible, reformulate query to point to more recent blocks

Fix

Add a NON_DETERMINISTIC_STATE_MESSAGES guard (case-insensitive substring match) checked before returning true from IsGenericDeterministicError:

  • state is not available
  • historical state that is not available
  • missing trie node

-32602/-32600 with revert or other genuine argument errors stay deterministic. The geth/reth/parity/ganache message-based functions are untouched.

Tests

Table-driven cases added to TestIsDeterministicError and TestIsGenericDeterministicError:

  • -32602 with state-unavailable messages (incl. the exact Monad production string) → false
  • -32602 with revert / plain "Invalid argument" → still true
  • -32600 unaffected
  • real geth/reth/parity/ganache messages → still true

All ./rpc/ tests pass.

Changelog

### Fixed entry added; the existing ### Changed -32602 note clarified with the exception.

IsGenericDeterministicError trusted the JSON-RPC code alone, so -32602
(and -32600) errors were always deemed deterministic. Some nodes reuse
-32602 for state/block unavailability (pruned node), which is transient
and node-capability dependent: an archive node, or the same node later,
answers the same call correctly. Downstream consumers cache deterministic
errors permanently, poisoning the entry forever.

Add NON_DETERMINISTIC_STATE_MESSAGES guard (case-insensitive substring)
excluding "state is not available", "historical state that is not
available" and "missing trie node". The last case matches the exact
error observed in production on Monad RPC.
@maoueh
maoueh merged commit 2e53ff6 into develop Jul 14, 2026
2 checks passed
@maoueh
maoueh deleted the feature/fix-wrong-determinstic-state-not-found-error branch July 14, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants