nautechsystems/nautilus_trader · error

invalid negative {name} quantity

Error message

invalid negative {name} quantity

What it means

Thrown when a bid or ask level's `qty_mantissa` is negative and cannot be converted to the unsigned `u64` quantity mantissa. Quantities are inherently non-negative, so a negative mantissa indicates a malformed level payload.

Source

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

        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)
                    .map_err(|_| anyhow::anyhow!("order-book level index overflow"))?,
            );
            book.add(order, 0, sequence, ts_event);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-fetch the depth snapshot to rule out a transient bad payload.
  2. Inspect the raw JSON to locate the level with the negative quantity.
  3. Fix mock/fixture data to use non-negative quantity mantissas.
  4. Report a bug if a genuine Binance response contains negative quantities.
Defensive patterns

Strategy: validation

Validate before calling

fn quantities_non_negative(snapshot: &BinanceDepth) -> bool {
    snapshot.bids.iter().chain(snapshot.asks.iter()).all(|l| l.qty_mantissa >= 0)
}

Type guard

fn non_neg_qty(l: &BinancePriceLevel) -> bool { l.qty_mantissa >= 0 }

Try / catch

match client.request_book_snapshot(id, depth).await {
    Ok(book) => book,
    Err(e) if e.to_string().contains("negative") && e.to_string().contains("quantity") => retry_snapshot(id, depth).await?,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `request_book_snapshot` when any depth level carries a negative quantity mantissa in the `/api/v3/depth` response.

Common situations: Corrupted or synthetic responses from proxies/mocks; upstream encoding anomalies; hand-written test fixtures with negative quantities.

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/4cf66140458c3acb. Report an issue: GitHub.