{"record":{"id":"178cfd916a89d1c7","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-lot-sz-for-e","errorCode":null,"errorMessage":"Failed to parse `lot_sz` '{}' for {}: {e}","messagePattern":"Failed to parse `lot_sz` '(.+?)' for (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/common/parse.rs","lineNumber":1681,"sourceCode":"        .map(parse_millisecond_timestamp)\n        .ok_or_else(|| anyhow::anyhow!(\"`list_time` is required for {}\", definition.sprd_id))?;\n    let expiration_ns = definition\n        .exp_time\n        .map(parse_millisecond_timestamp)\n        .unwrap_or_default();\n    let ts_event = definition\n        .u_time\n        .map_or(ts_init, parse_millisecond_timestamp);\n\n    let price_increment = Price::from_str(&definition.tick_sz).map_err(|e| {\n        anyhow::anyhow!(\n            \"Failed to parse `tick_sz` '{}' for {}: {e}\",\n            definition.tick_sz,\n            definition.sprd_id\n        )\n    })?;\n    let size_increment = Quantity::from_str(&definition.lot_sz).map_err(|e| {\n        anyhow::anyhow!(\n            \"Failed to parse `lot_sz` '{}' for {}: {e}\",\n            definition.lot_sz,\n            definition.sprd_id\n        )\n    })?;\n    let min_quantity = if definition.min_sz.is_empty() {\n        None\n    } else {\n        Some(Quantity::from_str(&definition.min_sz).map_err(|e| {\n            anyhow::anyhow!(\n                \"Failed to parse `min_sz` '{}' for {}: {e}\",\n                definition.min_sz,\n                definition.sprd_id\n            )\n        })?)\n    };\n\n    let info = Some(build_spread_info(definition));","sourceCodeStart":1663,"sourceCodeEnd":1699,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/common/parse.rs#L1663-L1699","documentation":"Venue-data parse failure in parse_spread_instrument: OKX's lot_sz (lot size / size increment) string for the spread instrument cannot be parsed into a Quantity; the message includes the raw string and instrument id.","triggerScenarios":"Calling parse_spread_instrument when definition.lot_sz is empty or not a valid decimal string (e.g. '0.001 BTC' or missing after a schema change).","commonSituations":"Bad fixtures or cached definitions; serde deserialization leaving lot_sz empty when OKX omits the field; copy/paste mistakes in stored instrument metadata.","solutions":["Verify lot_sz in the failing payload is a valid non-empty decimal string","Re-fetch spread instrument definitions from the live OKX endpoint","Fix field-name/casing mismatches (lotSz -> lot_sz with serde rename)","Default empty lot_sz to a known-safe increment if the instrument is still tradeable"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn lot_sz_valid(def: &OKXSpreadInstrument) -> bool {\n    !def.lot_sz.is_empty() && def.lot_sz.parse::<rust_decimal::Decimal>().is_ok()\n}","typeGuard":null,"tryCatchPattern":"let size_increment = match parse_spread_instrument(&definition, ts_init) {\n    Ok(inst) => inst,\n    Err(e) => { tracing::error!(\"lot_sz parse failed for {}: {e:#}\", definition.sprd_id); return; }\n};","preventionTips":["Validate lot_sz at ingestion time, before caching","Watch for OKX schema changes in /sprd/instruments","Trim/normalize numeric strings before parsing"],"tags":["rust","okx","parsing","quantity"],"backgroundTag":"invalid-argument-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}