nautechsystems/nautilus_trader · error

invalid price ` ` at precision

Error message

invalid price `{value}` at precision {precision}: {e}

What it means

After the string parses as a Decimal, parse_price calls Price::from_decimal_dp to build a Nautilus Price at the requested precision. This error means the decimal value is out of Price's representable range at that precision (or the precision conversion itself failed) — e.g. a price far beyond the fixed-precision mantissa capacity, or more fractional digits than the requested precision can hold without loss. The value and precision are included in the message.

Solutions

  1. Check that the precision argument matches the market's actual price_decimals from orderBookDetails.
  2. Validate the price against the instrument's price band / plausible range before parsing and reject absurd values upstream.
  3. Verify the raw payload — a value this large usually indicates a corrupted or fabricated message; drop the update and log the raw string.
  4. If legitimate values are being rejected, confirm you are not accidentally passing an exponent-scaled mantissa instead of the human-readable price.

Example fix

// before
let price = parse_price(value_str, precision)?;
// after
let price = parse_price(value_str, market.price_decimals)?;
anyhow::ensure!(price > Price::zero(), "price {} out of band", price);
Defensive patterns

Strategy: validation

Validate before calling

fn price_plausible(value: &str, max_price: f64) -> bool {
    value.parse::<f64>().map(|v| v.is_finite() && v > 0.0 && v <= max_price).unwrap_or(false)
}

Try / catch

match parse_price(raw, precision) {
    Ok(p) => p,
    Err(e) if e.to_string().contains("at precision") => {
        tracing::error!(raw = %raw, "price out of Price range; dropping update");
        return Ok(());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling parse_price with a valid decimal string whose magnitude overflows Price's fixed-point range (astronomically large value), or a value with more decimal places than the requested precision in contexts where from_decimal_dp rejects the conversion.

Common situations: A corrupt or malicious feed payload with a 30-digit price; misconfigured precision (e.g. precision=2 for a value like "0.000001"); test cases probing Price bounds with f64::MAX-style literals.

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/15b964ae5034c13c. Report an issue: GitHub.

Appendix: source

Thrown at crates/adapters/lighter/src/common/parse.rs:99

        anyhow::anyhow!("Quantity overflow for ticks={ticks}, decimals={decimals}: {e}")
    })
}

/// Converts a decimal string into a Nautilus [`Price`] at the requested precision.
///
/// # Errors
///
/// Returns an error if the string is not a decimal, if `precision` exceeds
/// [`MAX_DECIMALS`], or if the resulting value is out of range.
pub fn parse_price(value: &str, precision: u8) -> anyhow::Result<Price> {
    anyhow::ensure!(
        precision <= MAX_DECIMALS,
        "price precision {precision} exceeds maximum {MAX_DECIMALS}",
    );
    let decimal =
        Decimal::from_str(value).map_err(|e| anyhow::anyhow!("invalid price `{value}`: {e}"))?;
    Price::from_decimal_dp(decimal, precision)
        .map_err(|e| anyhow::anyhow!("invalid price `{value}` at precision {precision}: {e}"))
}

/// Converts a decimal string into a non-negative Nautilus [`Quantity`].
///
/// Zero is allowed because Lighter sends zero-size book levels to delete
/// existing orders.
///
/// # Errors
///
/// Returns an error if the string is not a decimal, if `precision` exceeds
/// [`MAX_DECIMALS`], if the value is negative, or if the resulting quantity
/// is out of range.
pub fn parse_quantity(value: &str, precision: u8) -> anyhow::Result<Quantity> {
    anyhow::ensure!(
        precision <= MAX_DECIMALS,
        "size precision {precision} exceeds maximum {MAX_DECIMALS}",
    );
    let decimal =

View on GitHub (pinned to 18893faf8b)