nautechsystems/nautilus_trader · error

Failed to convert Price raw value: {e}

Error message

Failed to convert Price raw value: {e}

What it means

u256_to_price mirrors u256_to_quantity for Price: after verifying the U256 stays under PRICE_RAW_MAX and scaling to the fixed precision, the scaled value is converted into PriceRaw via TryFrom. A failure there is wrapped as "Failed to convert Price raw value: {e}".

Source

Thrown at crates/adapters/blockchain/src/decode.rs:84

///
/// Returns an error if scaling overflows or the result exceeds [`PRICE_RAW_MAX`].
pub fn u256_to_price(amount: U256, decimals: u8) -> anyhow::Result<Price> {
    if decimals == 18 {
        check_raw_range(amount, U256::from(PRICE_RAW_MAX), "Price", "PRICE_RAW_MAX")?;
        return Ok(Price::from_wei(amount));
    }

    let precision = decimals.min(FIXED_PRECISION);
    let raw = scale_u256_to_raw(
        amount,
        decimals,
        FIXED_PRECISION,
        U256::from(PRICE_RAW_MAX),
        "Price",
        "PRICE_RAW_MAX",
    )?;
    let raw = PriceRaw::try_from(raw)
        .map_err(|e| anyhow::anyhow!("Failed to convert Price raw value: {e}"))?;
    Ok(Price::from_raw_checked(raw, precision)?)
}

fn scale_u256_to_raw(
    amount: U256,
    decimals: u8,
    fixed_precision: u8,
    raw_max: U256,
    type_name: &str,
    raw_max_name: &str,
) -> anyhow::Result<U256> {
    let raw = if decimals < fixed_precision {
        let scale = U256::from(10)
            .checked_pow(U256::from(fixed_precision - decimals))
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Scale 10^{} exceeds U256 while converting {type_name}",
                    fixed_precision - decimals

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Confirm the decimals argument reflects the correct quote/base token decimals for the price computation.
  2. Range-check the scaled value against PriceRaw::MAX (PRICE_RAW_MAX) before conversion.
  3. Normalize the price ratio (divide before scaling) if intermediate values are enormous.
  4. Audit upstream callers for double-scaling of reserve-derived ratios.
Defensive patterns

Strategy: validation

Validate before calling

// precondition check before conversion
let scaled = amount.checked_mul(U256::exp10(FIXED_PRECISION - decimals))
    .ok_or("overflow")?;
assert!(scaled <= U256::from(PRICE_RAW_MAX), "exceeds PRICE_RAW_MAX");

Type guard

fn fits_price_raw(v: U256) -> bool {
    v <= U256::from(PRICE_RAW_MAX)
}

Prevention

When it happens

Trigger: Converting a U256 price whose scaled raw representation overflows the PriceRaw integer type — typically a mis-scaled amount (wrong decimals) or an unreasonably huge price like raw reserve ratios with tiny denominator tokens.

Common situations: Quoting prices from pools with mismatched token decimals (e.g. 0-decimal tokens) producing astronomically large ratios; passing already-scaled values with decimals=0; wrong fixed precision assumptions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4d262e38afd34bfb. Report an issue: GitHub.