{"record":{"id":"6abe5c835e252a4b","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-type-name-to-f64-e","errorCode":null,"errorMessage":"Failed to parse {type_name} to f64: {e}","messagePattern":"Failed to parse (.+?) to f64: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/math.rs","lineNumber":52,"sourceCode":"    let amount = convert_to_f64(abs_amount, decimals, \"I256\")?;\n\n    Ok(if is_negative { -amount } else { amount })\n}\n\n/// Convert an alloy's U256 value to f64, accounting for token decimals.\n///\n/// # Errors\n///\n/// Returns an error if the U256 value cannot be parsed to f64.\npub fn convert_u256_to_f64(amount: U256, decimals: u8) -> anyhow::Result<f64> {\n    convert_to_f64(amount, decimals, \"U256\")\n}\n\nfn convert_to_f64(amount: impl Display, decimals: u8, type_name: &str) -> anyhow::Result<f64> {\n    let amount: f64 = amount\n        .to_string()\n        .parse()\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse {type_name} to f64: {e}\"))?;\n\n    let factor = 10f64.powi(i32::from(decimals));\n    Ok(amount / factor)\n}\n\n#[cfg(test)]\nmod tests {\n    use std::str::FromStr;\n\n    use alloy::primitives::{I256, U256};\n    use rstest::rstest;\n\n    use super::*;\n\n    #[rstest]\n    fn test_convert_positive_i256_to_f64() {\n        // Test with 6 decimals (USDC-like)\n        let amount = I256::from_str(\"1000000\").unwrap();","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/math.rs#L34-L70","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet amount: f64 = amount.to_string().parse()\n    .map_err(|e| anyhow::anyhow!(\"Failed to parse {type_name} to f64: {e}\"))?;\n// after (safe fallback to infinity with explicit signal)\nlet amount: f64 = amount.to_string().parse().unwrap_or_else(|_| {\n    tracing::error!(type_name, \"U256/I256 value not representable as f64\");\n    f64::INFINITY\n});","handlingStrategy":"try-catch","validationCode":"fn convertible_to_f64(amount: U256) -> bool {\n    // f64 max ~1.8e308; U256 max ~1.15e77 fits, but guard the string round-trip anyway\n    amount.to_string().parse::<f64>().is_ok()\n}\n// call convert_u256_to_f64 only after this check","typeGuard":"fn parses_as_f64(s: &str) -> bool {\n    s.parse::<f64>().is_ok()\n}","tryCatchPattern":"match convert_u256_to_f64(amount, decimals) {\n    Ok(v) if v.is_finite() => use(v),\n    Ok(_) => { /* infinity: value out of f64 range */ }\n    Err(e) => tracing::error!(%e, \"U256 to f64 conversion failed\"),\n}","preventionTips":["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."],"tags":["parsing","numeric-conversion","u256","f64"],"backgroundTag":"numeric-parse-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}