nautechsystems/nautilus_trader · error · anyhow::Error

Failed to parse {field}='{value}': {e}

Error message

Failed to parse {field}='{value}': {e}

What it means

A Binance exchangeInfo filter field was present as a string, but Price::from_str / Quantity::from_str rejected its contents. The domain types expect fixed-point decimal strings; values in other notations (e.g. scientific notation like "1e-8") or non-numeric text fail here.

Source

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

        f.get("filterType")
            .and_then(|v| v.as_str())
            .is_some_and(|t| t == filter_type)
    })
}

/// Parses a string field from a JSON value.
fn parse_filter_string(filter: &Value, field: &str) -> anyhow::Result<String> {
    filter
        .get(field)
        .and_then(|v| v.as_str())
        .map(String::from)
        .ok_or_else(|| anyhow::anyhow!("Missing field '{field}' in filter"))
}

/// Parses a Price from a filter field.
fn parse_filter_price(filter: &Value, field: &str) -> anyhow::Result<Price> {
    let value = parse_filter_string(filter, field)?;
    Price::from_str(&value).map_err(|e| anyhow::anyhow!("Failed to parse {field}='{value}': {e}"))
}

/// Parses a Quantity from a filter field.
fn parse_filter_quantity(filter: &Value, field: &str) -> anyhow::Result<Quantity> {
    let value = parse_filter_string(filter, field)?;
    Quantity::from_str(&value)
        .map_err(|e| anyhow::anyhow!("Failed to parse {field}='{value}': {e}"))
}

/// Parses the futures `MIN_NOTIONAL` filter into a `Money` value in `currency`.
///
/// Returns `None` when the filter is absent, the `notional` field cannot be
/// parsed, or the value is non-positive.
fn parse_futures_min_notional(filters: &[Value], currency: Currency) -> Option<Money> {
    let filter = get_filter(filters, "MIN_NOTIONAL")?;
    let raw = filter.get("notional").and_then(|v| v.as_str())?;
    let amount = f64::from_str(raw).ok()?;
    if amount <= 0.0 {

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Inspect the exact field=value printed in the message against the raw Binance response to identify the offending notation
  2. Update the adapter - numeric parsers gain coverage for new notations over time
  3. Report the field/value pair to maintainers if the live exchange really emits it

Example fix

// before: strict fixed-point parse
let price = Price::from_str(&value)?;

// after: normalize scientific notation first
let normalized = Decimal::from_str(&value)?.normalize().to_string();
let price = Price::from_str(&normalized)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_parseable_decimal(value: &str) -> bool {
    rust_decimal::Decimal::from_str(value.trim()).is_ok()
}
// check filter field values with this before Price/Quantity::from_str

Type guard

fn is_fixed_point_decimal_string(s: &str) -> bool {
    !s.is_empty()
        && s.chars().all(|c| c.is_ascii_digit() || c == '.')
        && s.matches('.').count() <= 1
}

Try / catch

let price = match Price::from_str(&value) {
    Ok(p) => p,
    Err(e) => {
        log::warn!("non-standard filter value {field}='{value}': {e} - normalizing via Decimal");
        let d = rust_decimal::Decimal::from_str(&value)?;
        Price::from_str(&d.normalize().to_string())?
    }
};

Prevention

When it happens

Trigger: Binance returns a filter value the strict decimal parser cannot read - scientific notation, empty string, or non-numeric text; or a mangled/captured payload altered the numeric formatting.

Common situations: Exchange-side formatting changes for very small ticks; responses rewritten by proxies; stale or corrupted captures being replayed.

Understand the failure class

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/0bb9a82451d6f4ac. Report an issue: GitHub.