Classifier
How non-revert errors are classified, the full rule table, and the decoder pipeline.
When the error isn't a decodable EVM revert, the decoder still gives you a useful message via classifyError.
Rule table
| Kind | Triggered by |
|---|---|
user_rejected | "User rejected", code: 4001, MetaMask ACTION_REJECTED, ... |
insufficient_funds | "insufficient funds for gas", "insufficient balance for transfer" |
nonce_too_low | "nonce too low", "invalid nonce", "nonce has already been used" |
replacement_underpriced | "replacement transaction underpriced", "replacement fee too low" |
transaction_underpriced | "transaction underpriced" |
intrinsic_gas_too_low | "intrinsic gas too low" |
gas_too_low | "out of gas", "gas limit too low" |
estimate_gas_failed | "unable to estimate gas", "gas required exceeds allowance" |
rate_limited | "too many requests", code: -32005, HTTP 429 |
method_not_supported | "the method X does not exist", "method not supported" |
timeout | "timed out", "deadline exceeded" |
chain_mismatch | "chain id mismatch", "wrong network", "unsupported chain" |
connection_refused | "ECONNREFUSED", "connection refused" |
network | "fetch failed", "network request failed" |
Each kind maps to a fixed, friendly English message. See src/core/errorClassifier.ts for the exact regex / code rules and messages.
Decoder pipeline
decoder.decode(error) runs these steps in order, returning the first one that produces a result:
- Cause traversal — walks
error.cause,error.cause.cause, ... and anyerrors[]siblings. Cycle-safe via aWeakSet. Hard-capped atMAX_CAUSE_DEPTH(16) to bound work on pathological inputs. - Revert extraction — reads
data/rawData/returnData/outputfields, or hex embedded inmessage/shortMessage/details/reason. - Standard decoders — if the selector is
0x08c379a0(Error(string)) or0x4e487b71(Panic(uint256)), decode without needing an ABI. Panic codes are translated into human messages (overflow, division-by-zero, out-of-bounds, etc.). - Custom ABI decoding — if the selector is registered, run viem's
decodeErrorResultagainst the matching ABI and return named args. - Classifier fallback — match the error tree against the rule table above (regex over
shortMessage/message/reason/detailsand EIP-1193 codes). - Unknown — return a best-effort message extracted from the error (or the configured
fallbackMessage).
Customising the fallback
const decoder = forViem({
fallbackMessage: 'Something went wrong. Please try again.',
});The fallback only applies when every earlier step has nothing useful to say — usually that means a thrown value with no message, no shortMessage, no data, and no recognisable selector or text.