nautechsystems/nautilus_trader · error
Failed to parse `min_sz` '{}' for {}: {e}
Error message
Failed to parse `min_sz` '{}' for {}: {e} What it means
parse_spread_instrument failed to parse the min_sz field of an OKX spread instrument definition into a Quantity; the venue returned a min-size string that is not a valid decimal number, so the instrument's minimum quantity cannot be represented and parsing is rejected.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:1691
let price_increment = Price::from_str(&definition.tick_sz).map_err(|e| {
anyhow::anyhow!(
"Failed to parse `tick_sz` '{}' for {}: {e}",
definition.tick_sz,
definition.sprd_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.sprd_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.sprd_id
)
})?)
};
let info = Some(build_spread_info(definition));
if spread_has_option_leg(definition) {
let instrument = CryptoOptionSpread::builder()
.instrument_id(instrument_id)
.raw_symbol(raw_symbol)
.underlying(underlying)
.quote_currency(quote_currency)
.settlement_currency(settlement_currency)
.is_inverse(is_inverse)
.strategy_type(Ustr::from(spread_type_literal(definition.sprd_type)))View on GitHub (pinned to 18893faf8b)
Solutions
- Check min_sz in the payload for placeholder or locale-formatted values and sanitize them
- Re-fetch the definition from OKX to get the canonical min_sz string
- Trim whitespace before parsing; treat placeholder strings as empty to get None
- Add a normalization step before Quantity::from_str
Example fix
// before
Some(Quantity::from_str(&definition.min_sz).map_err(|e| {
anyhow::anyhow!("Failed to parse `min_sz` '{}' for {}: {e}", definition.min_sz, definition.sprd_id)
})?)
// after
let min_sz = definition.min_sz.trim();
let min_quantity = if min_sz.is_empty() {
None
} else {
Some(Quantity::from_str(min_sz).map_err(|e| {
anyhow::anyhow!("Failed to parse `min_sz` '{}' for {}: {e}", min_sz, definition.sprd_id)
})?)
}; Defensive patterns
Strategy: validation
Validate before calling
fn min_sz_valid(def: &OKXSpreadInstrument) -> bool {
def.min_sz.is_empty() || def.min_sz.trim().parse::<rust_decimal::Decimal>().is_ok()
} Try / catch
match parse_spread_instrument(&definition, ts_init) {
Ok(inst) => Some(inst),
Err(e) => { tracing::warn!("min_sz rejected for {}: {e:#}", definition.sprd_id); None }
} Prevention
- Sanitize placeholder values ('N/A', '-') to empty before parsing
- Trim whitespace on all numeric fields
- Reject bad definitions at cache-write time
When it happens
Trigger: Calling parse_spread_instrument with a definition whose min_sz is populated but not a valid decimal (e.g. 'N/A', locale-formatted numbers, whitespace).
Common situations: Downstream systems exporting CSV/JSON with placeholder values like '-' or 'N/A'; encoding/locale issues; corrupted cached instrument metadata.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse fallback quantity for ord_id={}, sz='{}': {e
- Failed to convert quote-to-base quantity for ord_id={}, sz={
- Failed to parse filled quantity for ord_id={}, acc_fill_sz='
- Failed to parse base quantity for ord_id={}, sz='{}': {e}
- Failed to parse `lot_sz` '{}' for {}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/07bcdf5d5ecb45f6.
Report an issue: GitHub.