nautechsystems/nautilus_trader · error · anyhow::Error

invalid =

Error message

invalid {field}='{raw}': {e}

What it means

This is the base wrapper used for any required venue-supplied decimal string that fails `Decimal::from_str`. It means Binance sent a value in a field (price, quantity, commission, callback rate, fill report value) that is not a valid decimal number, and the adapter cannot proceed with that event.

Solutions

  1. Inspect the raw message and the offending field value to see why it is not a plain decimal
  2. Verify the event source (live vs testnet) returns real numeric strings
  3. Strip or normalize unexpected characters before handing raw strings to the parser
  4. Update the adapter if Binance changed the number formatting

Example fix

// before
let qty = parse_required_decimal(raw, "origQty")?;
// after
let qty = match parse_required_decimal(raw, "origQty") {
    Ok(q) => q,
    Err(e) => { error!("dropping malformed order event: {e}"); return Ok(()); }
};
Defensive patterns

Strategy: try-catch

Validate before calling

fn looks_like_decimal(s: &str) -> bool { !s.is_empty() && s.chars().all(|c| c.is_ascii_digit() || c == '.' || c == '-').then_some(()).is_some() }

Type guard

fn as_decimal_str(v: &serde_json::Value) -> Option<&str> { v.as_str().filter(|s| !s.is_empty() && s.parse::<Decimal>().is_ok()) }

Try / catch

match parse_required_decimal(raw, field) { Ok(d) => d, Err(e) => { error!("malformed field in venue message: {e}"); return Ok(()); } }

Prevention

When it happens

Trigger: Any code path calling parse_required_decimal via parse_required_quantity_at_precision, parse_required_price_at_precision, to_fill_report, parse_positive_price_at_precision, parse_callback_rate_basis_points, or parse_order_commission, when the raw string is empty, contains characters like '-' or 'null', or has locale formatting (thousand separators).

Common situations: WebSocket order-update or fill events carrying unusual values; testnet endpoints returning placeholder data; a REST response field null/absent coerced to an empty string; copy-pasted fixtures from other exchanges.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/common/parse.rs:214

}

/// Parses a venue price string into a `Price` at the given precision.
///
/// Returns `None` for unparsable, zero, or negative values. Goes through
/// `Decimal` for exact comparison semantics.
#[must_use]
pub(crate) fn parse_price_at_precision(raw: &str, precision: u8) -> Option<Price> {
    let decimal = Decimal::from_str(raw).ok()?;
    if !decimal.is_sign_positive() || decimal.is_zero() {
        return None;
    }

    Price::from_decimal_dp(decimal, precision).ok()
}

/// Parses a required venue decimal string.
pub(crate) fn parse_required_decimal(raw: &str, field: &str) -> anyhow::Result<Decimal> {
    Decimal::from_str(raw).map_err(|e| anyhow::anyhow!("invalid {field}='{raw}': {e}"))
}

/// Parses a required venue quantity string into a `Quantity` at the given precision.
pub(crate) fn parse_required_quantity_at_precision(
    raw: &str,
    precision: u8,
    field: &str,
) -> anyhow::Result<Quantity> {
    let decimal = parse_required_decimal(raw, field)?;
    Quantity::from_decimal_dp(decimal, precision)
        .map_err(|e| anyhow::anyhow!("invalid {field}='{raw}' at precision {precision}: {e}"))
}

/// Parses a required venue price string into a `Price` at the given precision.
pub(crate) fn parse_required_price_at_precision(
    raw: &str,
    precision: u8,
    field: &str,

View on GitHub (pinned to 18893faf8b)