nautechsystems/nautilus_trader · error · anyhow::Error

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

Error message

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

What it means

Second stage of required-quantity parsing: the string already parsed as a Decimal, but Quantity::from_decimal_dp cannot represent it at the requested fixed precision, so the error repeats the field, raw value, and adds the precision. Typical causes are negative values or values whose significant digits exceed what the fixed-point Quantity type can hold at that precision.

Source

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

    }

    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,
) -> anyhow::Result<Price> {
    let decimal = parse_required_decimal(raw, field)?;
    Price::from_decimal_dp(decimal, precision)
        .map_err(|e| anyhow::anyhow!("invalid {field}='{raw}' at precision {precision}: {e}"))
}

/// Re-precisions an existing `Quantity` to the given precision via `Decimal`.
#[must_use]
pub(crate) fn quantity_at_precision(quantity: Quantity, precision: u8) -> Option<Quantity> {
    Quantity::from_decimal_dp(quantity.as_decimal(), precision).ok()
}

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Check the raw value in the error message for a minus sign or unexpected magnitude.
  2. Confirm the venue semantics of the field; if it is a signed delta, handle the sign upstream rather than parsing it as a quantity.
  3. Verify how the precision argument is derived for that symbol/instrument and fix its source.
  4. If the venue response itself is inconsistent, capture the payload and report it to the adapter maintainers.

Example fix

// before: signed venue value parsed directly as a quantity
// parse_required_quantity_at_precision("-0.001", 8, "executedQty")?; // -> error

// after: resolve the sign first (only after confirming the venue reports magnitude here)
// let raw = raw.trim_start_matches('-');
// parse_required_quantity_at_precision(raw, 8, "executedQty")?;
Defensive patterns

Strategy: validation

Validate before calling

fn quantity_fits_at_precision(raw: &str, precision: u8) -> bool {
    let Ok(d) = rust_decimal::Decimal::from_str(raw) else { return false; };
    d.is_sign_positive() && nautilus_model::types::Quantity::from_decimal_dp(d, precision).is_ok()
}

Try / catch

match parse_required_quantity_at_precision(raw, precision, field) {
    Ok(qty) => qty,
    Err(e) => {
        tracing::error!(%field, %raw, %precision, "quantity conversion failed: {e:#}");
        return Ok(None); // degrade gracefully for this record
    }
}

Prevention

When it happens

Trigger: Calls into parse_required_quantity_at_precision where the venue decimal is negative (for example '-0.001') or where magnitude/scale cannot be represented by a Quantity at the passed precision.

Common situations: A venue field that legitimately carries a sign (fee-adjusted balance, liquidation delta) is fed to a parser expecting an unsigned quantity; precision inferred from a different venue field mismatches the value's scale; API version drift.

Related errors


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