{"record":{"id":"3fed3ace14874408","repo":"nautechsystems/nautilus_trader","slug":"missing-sz-for-algo-order","errorCode":null,"errorMessage":"Missing sz for algo order {}","messagePattern":"Missing sz for algo order (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/parse.rs","lineNumber":1714,"sourceCode":"    }\n}\n\nfn parse_algo_order_quantity(\n    msg: &OKXAlgoOrderMsg,\n    instrument: &InstrumentAny,\n) -> anyhow::Result<Quantity> {\n    if !msg.sz.is_empty() {\n        return parse_quantity(msg.sz.as_str(), instrument.size_precision());\n    }\n\n    if !msg.close_fraction.is_empty()\n        || !msg.sl_trigger_px.is_empty()\n        || !msg.tp_trigger_px.is_empty()\n    {\n        return Ok(Quantity::zero(instrument.size_precision()));\n    }\n\n    anyhow::bail!(\"Missing sz for algo order {}\", msg.algo_id)\n}\n\n/// Parses an OKX order message into a Nautilus order status report.\n///\n/// # Errors\n///\n/// Returns an error if order metadata or numeric values cannot be parsed.\npub fn parse_order_status_report(\n    msg: &OKXOrderMsg,\n    instrument: &InstrumentAny,\n    account_id: AccountId,\n    ts_init: UnixNanos,\n) -> anyhow::Result<OrderStatusReport> {\n    let client_order_id =\n        parse_parent_client_order_id(msg.algo_cl_ord_id.as_deref(), &msg.cl_ord_id);\n    let venue_order_id = VenueOrderId::new(msg.ord_id);\n    let order_side = OrderSide::from(msg.side);\n","sourceCodeStart":1696,"sourceCodeEnd":1732,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/parse.rs#L1696-L1732","documentation":"An OKX algo order message carries its size in sz. If sz is absent/empty, and the message also lacks any stop-loss/take-profit trigger fields (which would imply zero size), the parser cannot construct a quantity and bails with the algo_id in the message.","triggerScenarios":"Receiving an algo order update where msg.sz is None/empty and none of sl_trigger_px / tp_trigger_px / sl_trigger_px-ish fields are set, e.g. an amend or cancel push that strips sz.","commonSituations":"OKX pushing state-change updates for algo orders without full fields; partial snapshots; adapter subscribed to algo channel for order types it can't fully parse.","solutions":["Check whether the specific algo_id's message stream omits sz and whether your order type requires it","Include sz when placing the algo order so all updates carry it","Handle/prefilter these updates before parse_algo_order_quantity, or map messages without sz to a status-only event"],"exampleFix":"// before\n// sz empty and no tp/sl triggers -> bail\n// after: treat as size-less status update\nif msg.sz.is_none() {\n    return Ok(Quantity::zero(instrument.size_precision()));\n}","handlingStrategy":"type-guard","validationCode":"fn has_size(msg: &OKXAlgoOrderMsg) -> bool {\n    msg.sz.as_deref().map_or(false, |s| !s.is_empty())\n        || !msg.sl_trigger_px.is_empty()\n        || !msg.tp_trigger_px.is_empty()\n}","typeGuard":"fn is_fill_bearing(msg: &OKXAlgoOrderMsg) -> bool { msg.sz.as_deref().map_or(false, |s| !s.is_empty()) }","tryCatchPattern":"if !is_fill_bearing(&msg) { return Ok(None); } // skip status-only algo updates","preventionTips":["Always set sz when placing algo orders so updates carry it","Route algo status-only updates away from quantity parsing"],"tags":["okx","parsing","websocket","missing-field"],"backgroundTag":"missing-required-argument","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"}