nautechsystems/nautilus_trader · error

invalid {name} price: {e}

Error message

invalid {name} price: {e}

What it means

Thrown when converting a bid/ask level's price mantissa (with the snapshot's `price_exponent`) into a Nautilus `Price` fails — e.g. the value cannot be represented at the instrument's `price_precision`. The `name` is "bid" or "ask", identifying the failing side.

Source

Thrown at crates/adapters/binance/src/spot/http/client.rs:3076

        instrument_id: InstrumentId,
        instrument: &InstrumentAny,
        snapshot: &BinanceDepth,
        ts_event: UnixNanos,
    ) -> anyhow::Result<OrderBook> {
        let sequence = u64::try_from(snapshot.last_update_id)
            .map_err(|_| anyhow::anyhow!("invalid negative order-book update ID"))?;
        let mut book = OrderBook::new(instrument_id, BookType::L2_MBP);
        let mut add_level = |level: &super::models::BinancePriceLevel,
                             side: OrderSide,
                             order_id: usize,
                             name: &str|
         -> anyhow::Result<()> {
            let price = Price::from_mantissa_exponent_checked(
                level.price_mantissa,
                snapshot.price_exponent,
                instrument.price_precision(),
            )
            .map_err(|e| anyhow::anyhow!("invalid {name} price: {e}"))?;
            anyhow::ensure!(price.is_positive(), "invalid non-positive {name} price");
            let qty_mantissa = u64::try_from(level.qty_mantissa)
                .map_err(|_| anyhow::anyhow!("invalid negative {name} quantity"))?;
            let quantity = Quantity::from_mantissa_exponent_checked(
                qty_mantissa,
                snapshot.qty_exponent,
                instrument.size_precision(),
            )
            .map_err(|e| anyhow::anyhow!("invalid {name} quantity: {e}"))?;
            anyhow::ensure!(
                quantity.is_positive(),
                "invalid non-positive {name} quantity"
            );
            let order = BookOrder::new(
                side,
                price,
                quantity,
                u64::try_from(order_id)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Refresh the instruments cache so `price_precision` matches current Binance filters (PRICE_FILTER tickSize).
  2. Re-fetch the depth snapshot to rule out a transient malformed payload.
  3. Check the error's inner `{e}` message for the exact Price conversion failure.
  4. Verify the adapter version matches the current Binance Spot API price-exponent encoding.

Example fix

// before: assuming cached instrument is current
let book = client.request_book_snapshot(instrument_id, depth).await?;
// after: reload instruments before requesting the book
client.reload_instruments().await?;
let book = client.request_book_snapshot(instrument_id, depth).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn price_fits_precision(level_price: i64, exponent: i32, precision: u8) -> bool {
    // level price must be representable at the instrument's price precision
    (exponent >= -(precision as i32)) || level_price % 10 == 0
}

Type guard

fn valid_level(level: &BinancePriceLevel) -> bool { level.price_mantissa > 0 }

Try / catch

match client.request_book_snapshot(id, depth).await {
    Ok(book) => book,
    Err(e) if e.to_string().contains("invalid bid price") || e.to_string().contains("invalid ask price") => {
        reload_instruments_and_retry(id, depth).await?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `request_book_snapshot` when a level's `price_mantissa` combined with `price_exponent` cannot produce a valid `Price` at `instrument.price_precision()` — typically an exponent/precision mismatch between the cached instrument definition and the snapshot.

Common situations: Stale or missing instrument definitions in the adapter cache so precision doesn't match the exchange data; a corrupted depth payload with absurd price values; tick-size/precision changes on the exchange after an instrument update.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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