nautechsystems/nautilus_trader · error
Failed to parse {type_name} to f64: {e}
Error message
Failed to parse {type_name} to f64: {e} What it means
convert_to_f64 stringifies a U256/I256 amount and parses it back as f64, then scales by 10^decimals. The parse should never fail for decimal integer strings, so this error indicates an invariant violation — the Display output of the integer could not be parsed as f64 (e.g. an 'inf'/'NaN'-like string or a value that overflowed f64 parsing).
Source
Thrown at crates/adapters/blockchain/src/math.rs:52
let amount = convert_to_f64(abs_amount, decimals, "I256")?;
Ok(if is_negative { -amount } else { amount })
}
/// Convert an alloy's U256 value to f64, accounting for token decimals.
///
/// # Errors
///
/// Returns an error if the U256 value cannot be parsed to f64.
pub fn convert_u256_to_f64(amount: U256, decimals: u8) -> anyhow::Result<f64> {
convert_to_f64(amount, decimals, "U256")
}
fn convert_to_f64(amount: impl Display, decimals: u8, type_name: &str) -> anyhow::Result<f64> {
let amount: f64 = amount
.to_string()
.parse()
.map_err(|e| anyhow::anyhow!("Failed to parse {type_name} to f64: {e}"))?;
let factor = 10f64.powi(i32::from(decimals));
Ok(amount / factor)
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use alloy::primitives::{I256, U256};
use rstest::rstest;
use super::*;
#[rstest]
fn test_convert_positive_i256_to_f64() {
// Test with 6 decimals (USDC-like)
let amount = I256::from_str("1000000").unwrap();View on GitHub (pinned to 18893faf8b)
Solutions
- Check the actual string being parsed by logging amount.to_string(); it should be a plain decimal integer.
- Verify the input value is a legitimate U256/I256 from decoded event data, not a corrupted or wrapped value.
- If values can exceed f64 range with 0 decimals, keep amounts in U256/Decimal until final presentation instead of converting to f64.
- Consider replacing the string round-trip with TryFrom<f64>-free arithmetic to remove the parse failure mode.
Example fix
// before
let amount: f64 = amount.to_string().parse()
.map_err(|e| anyhow::anyhow!("Failed to parse {type_name} to f64: {e}"))?;
// after (safe fallback to infinity with explicit signal)
let amount: f64 = amount.to_string().parse().unwrap_or_else(|_| {
tracing::error!(type_name, "U256/I256 value not representable as f64");
f64::INFINITY
}); Defensive patterns
Strategy: try-catch
Validate before calling
fn convertible_to_f64(amount: U256) -> bool {
// f64 max ~1.8e308; U256 max ~1.15e77 fits, but guard the string round-trip anyway
amount.to_string().parse::<f64>().is_ok()
}
// call convert_u256_to_f64 only after this check Type guard
fn parses_as_f64(s: &str) -> bool {
s.parse::<f64>().is_ok()
} Try / catch
match convert_u256_to_f64(amount, decimals) {
Ok(v) if v.is_finite() => use(v),
Ok(_) => { /* infinity: value out of f64 range */ }
Err(e) => tracing::error!(%e, "U256 to f64 conversion failed"),
} Prevention
- Keep raw amounts in U256/Decimal; convert to f64 only at presentation boundaries.
- Beware precision loss above 2^53 when using f64 for money amounts.
- Log the stringified amount when conversion fails to spot corrupted upstream data.
When it happens
Trigger: Calling convert_i256_to_f64 or convert_u256_to_f64 with an amount whose string form is not a valid f64 literal — practically only when a value renders as something non-numeric or exceeds f64's representable range (>= ~1.8e308), which is essentially unreachable via normal U256 usage.
Common situations: Converting a U256 near its maximum with 0 decimals is still ~1e77, well within f64 range, so hitting this in practice points to a bug, a wrapped/negative value mishandled upstream, or a custom Display impl.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- WETH balance overflow for included transaction {tx_hash} at
- Invalid `external_order_claims` instrument ID {claim}: {e}
- Invalid scientific notation exponent '{exponent}': must be a
- {FAILED}: {e}
- {FAILED}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6abe5c835e252a4b.
Report an issue: GitHub.