{"record":{"id":"9b7186ef7c621298","repo":"nautechsystems/nautilus_trader","slug":"failed-to-convert-quantity-raw-value-e","errorCode":null,"errorMessage":"Failed to convert Quantity raw value: {e}","messagePattern":"Failed to convert Quantity raw value: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/decode.rs","lineNumber":54,"sourceCode":"            amount,\n            U256::from(QUANTITY_RAW_MAX),\n            \"Quantity\",\n            \"QUANTITY_RAW_MAX\",\n        )?;\n        return Ok(Quantity::from_wei(amount));\n    }\n\n    let precision = decimals.min(FIXED_PRECISION);\n    let raw = scale_u256_to_raw(\n        amount,\n        decimals,\n        FIXED_PRECISION,\n        U256::from(QUANTITY_RAW_MAX),\n        \"Quantity\",\n        \"QUANTITY_RAW_MAX\",\n    )?;\n    let raw = QuantityRaw::try_from(raw)\n        .map_err(|e| anyhow::anyhow!(\"Failed to convert Quantity raw value: {e}\"))?;\n    Ok(Quantity::from_raw_checked(raw, precision)?)\n}\n\n/// Convert a `U256` amount to [`Price`].\n///\n/// - If `decimals == 18`, the value represents wei and uses the dedicated lossless\n///   `Price::from_wei` constructor.\n/// - Other precisions use checked integer scaling and clamp `decimals` to\n///   [`FIXED_PRECISION`]. Discarded source digits are rounded half to even.\n///\n/// # Errors\n///\n/// Returns an error if scaling overflows or the result exceeds [`PRICE_RAW_MAX`].\npub fn u256_to_price(amount: U256, decimals: u8) -> anyhow::Result<Price> {\n    if decimals == 18 {\n        check_raw_range(amount, U256::from(PRICE_RAW_MAX), \"Price\", \"PRICE_RAW_MAX\")?;\n        return Ok(Price::from_wei(amount));\n    }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/decode.rs#L36-L72","documentation":"u256_to_quantity scales a U256 amount by the token decimals to the Quantity fixed precision, then converts to QuantityRaw (the domain raw i128-style representation) via TryFrom. If the scaled value does not fit into QuantityRaw, the conversion fails and is wrapped with this message. The bounded domain checks (QUANTITY_RAW_MAX) have already passed, so this fires on a TryFrom narrowing failure.","triggerScenarios":"Converting a U256 token amount whose scaled raw value (amount × 10^(fixed_precision − decimals)) exceeds the QuantityRaw integer type's maximum — extremely large token balances or precision mismatches.","commonSituations":"Tokens with very few decimals (0–6) holding enormous supplies; decoding raw values mis-scaled by passing the wrong decimals for the token; contract responses read with wrong ABI scale.","solutions":["Verify the token's decimals value passed to u256_to_quantity matches the on-chain token decimals.","Range-check the scaled amount against QuantityRaw::MAX (QUANTITY_RAW_MAX) before conversion.","If the balance genuinely exceeds the domain max, the value cannot be represented as a Nautilus Quantity — handle/scale at a higher level.","Check that the raw value was not multiplied twice (e.g. already-adjusted wei passed with decimals=0)."],"exampleFix":"// before\nlet qty = u256_to_quantity(raw_balance, 0)?; // decimals guessed wrong\n\n// after\nlet decimals = erc20.decimals().call().await?; // fetch on-chain decimals\nlet qty = u256_to_quantity(raw_balance, decimals)?;","handlingStrategy":"validation","validationCode":"// precondition check before conversion\nlet scale = 10u32.checked_pow(FIXED_PRECISION - decimals)\n    .ok_or(\"scale overflow\")?;\nlet scaled = amount.checked_mul(U256::from(scale))\n    .ok_or(\"amount overflow\")?;\nassert!(scaled <= U256::from(QUANTITY_RAW_MAX), \"exceeds QUANTITY_RAW_MAX\");","typeGuard":"fn fits_quantity_raw(v: U256) -> bool {\n    v <= U256::from(QUANTITY_RAW_MAX)\n}","tryCatchPattern":null,"preventionTips":["Fetch token decimals on-chain instead of guessing","Range-check scaled amounts against QUANTITY_RAW_MAX before converting","Watch for double-scaling of already-adjusted values"],"tags":["u256","quantity","overflow","decoding"],"backgroundTag":"value-out-of-range","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"}