nautechsystems/nautilus_trader · error

Failed to parse `max_mkt_sz` '{}' for {}: {e}

Error message

Failed to parse `max_mkt_sz` '{}' for {}: {e}

What it means

The optional `max_mkt_sz` field (maximum market-order size) is converted to a `Quantity`, and the string failed to parse. The field is optional: empty means None and no error; only a present-but-invalid value throws. This guards against a corrupted market-order size limit entering the instrument definition.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:1974

    })?;

    if definition.lot_sz.is_empty() {
        anyhow::bail!("`lot_sz` is empty for {}", definition.inst_id);
    }

    let size_increment = Quantity::from_str(&definition.lot_sz).map_err(|e| {
        anyhow::anyhow!(
            "Failed to parse `lot_sz` '{}' for {}: {e}",
            definition.lot_sz,
            definition.inst_id,
        )
    })?;
    let lot_size = Some(size_increment);
    let max_quantity = if definition.max_mkt_sz.is_empty() {
        None
    } else {
        Some(Quantity::from_str(&definition.max_mkt_sz).map_err(|e| {
            anyhow::anyhow!(
                "Failed to parse `max_mkt_sz` '{}' for {}: {e}",
                definition.max_mkt_sz,
                definition.inst_id,
            )
        })?)
    };
    let min_quantity = if definition.min_sz.is_empty() {
        None
    } else {
        Some(Quantity::from_str(&definition.min_sz).map_err(|e| {
            anyhow::anyhow!(
                "Failed to parse `min_sz` '{}' for {}: {e}",
                definition.min_sz,
                definition.inst_id,
            )
        })?)
    };
    let max_notional: Option<Money> = None;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect definition.max_mkt_sz for the failing inst_id; verify it is a plain decimal string.
  2. Confirm the value matches the OKX instruments API response for that instId.
  3. Fix the source data (fixture/cache); if the exchange value is genuinely unusable, clear the field so it parses as None.
  4. Trim/normalize the string (e.g. strip whitespace or units) before parsing if that is the failure cause.

Example fix

// before
Some(Quantity::from_str(&definition.max_mkt_sz).map_err(|e| ...)?)
// after
let v = definition.max_mkt_sz.trim();
Some(Quantity::from_str(v).map_err(|e| ...)?)
Defensive patterns

Strategy: validation

Validate before calling

// max_mkt_sz is optional: empty is fine, only validate when present
fn valid_optional_decimal(s: &str) -> bool {
    let t = s.trim();
    t.is_empty() || t.parse::<f64>().is_ok()
}
assert!(valid_optional_decimal(&definition.max_mkt_sz), "bad max_mkt_sz");

Type guard

fn optional_quantity(s: &str) -> Option<&str> {
    let t = s.trim();
    if t.is_empty() { None } else if t.parse::<f64>().is_ok() { Some(t) } else { None }
}

Try / catch

match parse_instrument_with_parser(&definition, ts_init) {
    Ok(inst) => inst,
    Err(e) if e.to_string().contains("max_mkt_sz") => {
        tracing::warn!(inst_id = %definition.inst_id, "bad max_mkt_sz; continuing without limit: {e}");
        continue;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: parse_common_instrument_data receives an OkxInstrumentDef with a non-empty max_mkt_sz that Quantity::from_str cannot parse (bad decimal, scientific notation, placeholder text) — typically from a malformed API payload or edited fixture.

Common situations: OKX returning placeholder or corrupted values for rarely-used fields; hand-built test fixtures; version drift between cached snapshots and the current parser expectations.

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/7977f38a9265ef4a. Report an issue: GitHub.