nautechsystems/nautilus_trader · error

invalid {field} `{raw}`

Error message

invalid {field} `{raw}`

What it means

parse_non_negative_quantity parses a Binance stream quantity field into a domain Quantity. It errors when the raw string is not a valid Decimal, is negative, or cannot be represented at the instrument's precision. The message names the offending field and the raw value.

Source

Thrown at crates/adapters/binance/src/spot/websocket/public_json/parse.rs:62

        parse::{parse_millis_or_init, parse_price_at_precision, parse_quantity_at_precision},
    },
    data_types::BinanceSpotTicker,
};

fn parse_positive_price(raw: &str, precision: u8, field: &str) -> anyhow::Result<Price> {
    parse_price_at_precision(raw, precision)
        .ok_or_else(|| anyhow::anyhow!("invalid {field} `{raw}`"))
}

fn parse_positive_quantity(raw: &str, precision: u8, field: &str) -> anyhow::Result<Quantity> {
    parse_quantity_at_precision(raw, precision)
        .ok_or_else(|| anyhow::anyhow!("invalid {field} `{raw}`"))
}

fn parse_non_negative_quantity(raw: &str, precision: u8, field: &str) -> anyhow::Result<Quantity> {
    let decimal = Decimal::from_str(raw).with_context(|| format!("invalid {field} `{raw}`"))?;
    if decimal.is_sign_negative() {
        anyhow::bail!("invalid {field} `{raw}`");
    }

    Quantity::from_decimal_dp(decimal, precision)
        .map_err(|e| anyhow::anyhow!("invalid {field} `{raw}`: {e}"))
}

/// Parses a trade message into a `TradeTick`.
///
/// # Errors
///
/// Returns an error if price or quantity fields cannot be parsed.
pub fn parse_trade(
    msg: &BinanceSpotTradeMsg,
    instrument: &InstrumentAny,
    ts_init: UnixNanos,
) -> anyhow::Result<TradeTick> {
    let instrument_id = instrument.id();
    let price_precision = instrument.price_precision();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log/inspect the `{field}` and `{raw}` values in the message to see the exact malformed payload.
  2. Verify the instrument's precision setting matches Binance's tick size for that symbol.
  3. Confirm the message came from the expected Binance JSON schema; update parsing if Binance changed the format.
  4. If precision mismatch is the cause, configure the instrument with Binance's published precision.

Example fix

// before
let qty = parse_non_negative_quantity(raw, 8, "quantity")?; // fails when instrument precision is 2
// after
let qty = parse_non_negative_quantity(raw, instrument.price_precision(), "quantity")?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_quantity(raw: &str) -> bool {
    !raw.is_empty() && rust_decimal::Decimal::from_str(raw).map(|d| !d.is_sign_negative()).unwrap_or(false)
}

Try / catch

match parse_non_negative_quantity(raw, precision, "quantity") {
    Ok(q) => q,
    Err(e) => { log::warn!("skipping malformed stream payload: {e}"); continue; }
}

Prevention

When it happens

Trigger: parse_book_ticker, parse_depth_diff, or parse_kline receiving a quantity string that fails Decimal::from_str (empty, non-numeric), has a negative sign, or exceeds the allowed decimal precision in Quantity::from_decimal_dp.

Common situations: Binance schema changes producing unexpected payload fields; instrument precision configured tighter than Binance publishes; corrupted/truncated WS frames yielding garbage strings; test fixtures with malformed values.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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