nautechsystems/nautilus_trader · error
Failed to parse {method} result '{hex_string}': {e}
Error message
Failed to parse {method} result '{hex_string}': {e} What it means
Thrown by `parse_hex_quantity_result` when the JSON-RPC result string exists but is not a valid hex quantity parseable by `u128::from_str_radix` after stripping the `0x` prefix. This protects callers from silently treating malformed node data as a numeric quantity.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:1031
/// Classifies a broadcast transport failure: a timeout after sending reconciles through the
/// persisted record. Any other transport failure is treated as ambiguous-after-send too, even
/// though some (for example connection refused) may never have reached the node; the HTTP
/// client does not expose the connect-phase distinction, so the conservative outcome never
/// risks a rebroadcast. Sanitized to never carry the endpoint URL or request payload.
fn classify_broadcast_transport_error(error: &HttpClientError) -> BroadcastError {
match error {
HttpClientError::TimeoutError(_) => BroadcastError::TimeoutAfterSend,
_ => BroadcastError::Failed("transport error".to_string()),
}
}
/// Parses a required hex-quantity JSON-RPC result, erroring on a missing result.
fn parse_hex_quantity_result(method: &str, result: Option<String>) -> anyhow::Result<u128> {
let hex_string = result.ok_or_else(|| anyhow::anyhow!("{method} returned no result"))?;
let stripped = hex_string.strip_prefix("0x").unwrap_or(&hex_string);
u128::from_str_radix(stripped, 16)
.map_err(|e| anyhow::anyhow!("Failed to parse {method} result '{hex_string}': {e}"))
}
#[cfg(test)]
pub(crate) mod tests {
use alloy::primitives::{address, b256};
use rstest::rstest;
use super::*;
#[rstest]
fn rpc_response_preview_truncates_on_utf8_boundary() {
let raw = format!("{}é", "a".repeat(499));
let preview = rpc_response_preview(&raw);
assert_eq!(
preview,
format!("{}... (truncated, 501 bytes total)", "a".repeat(499))View on GitHub (pinned to 18893faf8b)
Solutions
- Log/inspect the raw result string to see what the node actually returned.
- Point the client at a spec-compliant EVM node; verify with curl that eth_chainId returns e.g. "0x1".
- If values may exceed u128 in your chain, this adapter's u128 bound is exceeded — use a node whose quantities fit or handle the value upstream.
- Add a fallback endpoint that returns well-formed hex quantities.
Example fix
// before
// mock server returns {"result": "1"} (decimal) -> parse fails
// after
// mock server returns {"result": "0x1"} (hex quantity) Defensive patterns
Strategy: validation
Validate before calling
fn is_hex_quantity(s: &str) -> bool {
let body = s.strip_prefix("0x").unwrap_or(s);
!body.is_empty() && body.chars().all(|c| c.is_ascii_hexdigit())
&& body.parse::<u128>().map_err(|_| u128::from_str_radix(body, 16).is_ok())
&& u128::from_str_radix(body, 16).is_ok()
}
// validate the raw result string before passing it downstream Type guard
fn as_hex_quantity(v: &serde_json::Value) -> Option<u128> {
let s = v.as_str()?;
let body = s.strip_prefix("0x").unwrap_or(s);
u128::from_str_radix(body, 16).ok()
} Try / catch
match client.chain_id() {
Err(e) if e.to_string().starts_with("Failed to parse eth_chainId result") => {
tracing::error!("non-compliant node returned a non-hex quantity; audit endpoint");
Err(e)
}
other => other,
} Prevention
- Test mock/proxy servers against spec-compliant responses (hex quantities like "0x1", not "1").
- Curl eth_chainId when integrating a new node to confirm hex-quantity formatting.
- Be aware the adapter parses into u128; reject chains whose quantities can exceed it.
When it happens
Trigger: A method like eth_chainId/eth_getTransactionCount/eth_estimateGas/eth_maxPriorityFeePerGas returning a non-hex-quantity string — e.g. a decimal string, a 0x-prefixed value exceeding u128, an empty string, or garbage text — reaching `u128::from_str_radix`.
Common situations: Non-EVM or misbehaving mock/proxy servers that return decimal numbers as strings; quantity fields exceeding u128 range (rare but possible for some values); provider returning error text inside `result` instead of `error`.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid hex u64: {e}
- Invalid hex u32: {e}
- Failed to parse eth call response: {e} Raw response: {previe
- Failed to parse eth_call response
- Failed to decode eth_call response
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b7b90fe42e666ebf.
Report an issue: GitHub.