{"record":{"id":"e299f15529774599","repo":"nautechsystems/nautilus_trader","slug":"cannot-determine-fill-quantity-fill-sz-is-empty-z","errorCode":null,"errorMessage":"Cannot determine fill quantity: fill_sz is empty/zero and acc_fill_sz is empty/zero","messagePattern":"Cannot determine fill quantity: fill_sz is empty/zero and acc_fill_sz is empty/zero","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/parse.rs","lineNumber":2136,"sourceCode":"                    anyhow::bail!(\n                        \"Cumulative fill went backwards: acc_fill_sz='{acc_fill_sz}' < previous_filled_qty={prev_qty} \\\n                         (possible stale data after reconnect)\"\n                    );\n                }\n                let incremental = current_filled - prev_qty;\n                if incremental.is_zero() {\n                    log::debug!(\n                        \"Skipping duplicate fill: acc_fill_sz='{acc_fill_sz}' unchanged from previous={prev_qty}\"\n                    );\n                    return Ok(None);\n                }\n                incremental\n            } else {\n                // First fill, use accumulated as incremental\n                current_filled\n            }\n        } else {\n            anyhow::bail!(\n                \"Cannot determine fill quantity: fill_sz is empty/zero and acc_fill_sz is empty/zero\"\n            );\n        }\n    } else {\n        anyhow::bail!(\n            \"Cannot determine fill quantity: fill_sz='{}' and acc_fill_sz is None\",\n            msg.fill_sz\n        );\n    };\n\n    let fee_str = msg\n        .fee\n        .as_deref()\n        .filter(|fee| !fee.trim().is_empty())\n        .ok_or_else(|| anyhow::anyhow!(\"missing fee for fill report inst_id={}\", msg.inst_id))?;\n    let fee_dec = Decimal::from_str(fee_str)\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse fee '{fee_str}': {e}\"))?;\n","sourceCodeStart":2118,"sourceCodeEnd":2154,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/parse.rs#L2118-L2154","documentation":"A fill quantity can only be derived from fill_sz (incremental) or acc_fill_sz (cumulative). When both are empty or zero the parser cannot produce a meaningful fill and bails, since emitting a zero fill would be ambiguous.","triggerScenarios":"An orders-channel update where fill_sz is empty or '0' and acc_fill_sz is also empty or zero — e.g. a status-only update (canceled/amended) routed through parse_fill_report, or a first snapshot with no fills yet.","commonSituations":"Order state changes (cancel/modify) delivered on the same channel and mistaken for fills; malformed fixtures; OKX field semantics differences between channels.","solutions":["Only route updates with status 'live'/'partially_filled' and a nonzero fill into parse_fill_report; treat others as status events","Return None instead of an error for zero-size updates if your flow expects them","Log the raw message and confirm which OKX channel it came from"],"exampleFix":"// before\nlet fill = parse_fill_report(&msg, instrument, prev, ...)?; // bails on zero sizes\n// after\nif msg.fill_sz.is_none() && msg.acc_fill_sz.is_none() {\n    return Ok(None); // status-only update\n}","handlingStrategy":"type-guard","validationCode":"fn is_zero_fill(msg: &OKXOrderMsg) -> bool {\n    let zero = |s: Option<&String>| s.map_or(true, |v| v.is_empty() || v == \"0\");\n    zero(msg.fill_sz.as_ref()) && zero(msg.acc_fill_sz.as_ref())\n}","typeGuard":"fn has_fill_data(msg: &OKXOrderMsg) -> bool { !is_zero_fill(msg) }","tryCatchPattern":"if is_zero_fill(&msg) { return Ok(None); } // status-only update, not a fill","preventionTips":["Only call parse_fill_report for statuses that imply fills (live/partially_filled)","Keep test fixtures consistent with real OKX payloads","Handle status-only updates as OrderStatusReports, not fills"],"tags":["okx","parsing","websocket","missing-field"],"backgroundTag":"unexpected-api-response-shape","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"}