{"record":{"id":"534b423c93217eee","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-tick-sz-for-e","errorCode":null,"errorMessage":"Failed to parse `tick_sz` '{}' for {}: {e}","messagePattern":"Failed to parse `tick_sz` '(.+?)' for (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/common/parse.rs","lineNumber":1674,"sourceCode":"        Currency::get_or_create_crypto_with_context(definition.base_ccy, Some(&context));\n    let quote_currency =\n        Currency::get_or_create_crypto_with_context(definition.quote_ccy, Some(&context));\n    let settlement_currency = spread_settlement_currency(definition, underlying, quote_currency);\n    let is_inverse = matches!(definition.sprd_type, OKXSpreadType::Inverse);\n    let activation_ns = definition\n        .list_time\n        .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}\",","sourceCodeStart":1656,"sourceCodeEnd":1692,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/common/parse.rs#L1656-L1692","documentation":"parse_spread_instrument parses the definition's tick_sz string into a Price to form the price increment. If tick_sz is empty or not a valid price string, the error is raised naming the value and sprd_id.","triggerScenarios":"Calling parse_spread_instrument when the spread definition's tick_sz is empty, malformed (e.g. contains units), or uses an unparseable numeric representation.","commonSituations":"Missing or truncated fields in cached/manual spread definitions; OKX payload changes; fixture typos such as tick_sz vs tickSz casing.","solutions":["Print the raw definition and verify tick_sz is a valid non-empty numeric string","Re-fetch instruments from OKX /sprd/instruments to replace the bad definition","Add a pre-parse guard treating empty tick_sz as an error with a clear message","Check for serde field-name/casing mismatches leaving tick_sz unset"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn tick_sz_valid(def: &OKXSpreadInstrument) -> bool {\n    !def.tick_sz.is_empty() && def.tick_sz.parse::<rust_decimal::Decimal>().is_ok()\n}","typeGuard":null,"tryCatchPattern":"let price_increment = match parse_spread_instrument(&definition, ts_init) {\n    Ok(inst) => inst,\n    Err(e) => { tracing::error!(\"tick_sz/lot_sz parse failed for {}: {e:#}\", definition.sprd_id); return; }\n};","preventionTips":["Check serde rename attributes so tickSz maps to tick_sz","Re-fetch definitions from the live endpoint rather than trusting stale caches","Add empty-string pre-checks with descriptive errors"],"tags":["rust","okx","parsing","price"],"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"}