{"record":{"id":"6bd75b275a73a0b6","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-fill-sz-e","errorCode":null,"errorMessage":"Failed to parse fill_sz='{}': {e}","messagePattern":"Failed to parse fill_sz='(.+?)': (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/parse.rs","lineNumber":2107,"sourceCode":"        &msg.avg_px\n    } else {\n        &msg.px\n    };\n    let last_px = parse_price(price_str, price_precision).map_err(|e| {\n        anyhow::anyhow!(\n            \"Failed to parse price (fill_px='{}', avg_px='{}', px='{}'): {}\",\n            msg.fill_px,\n            msg.avg_px,\n            msg.px,\n            e\n        )\n    })?;\n\n    // OKX provides fillSz (incremental fill) or accFillSz (cumulative total)\n    // If fillSz is provided, use it directly as the incremental fill quantity\n    let last_qty = if !msg.fill_sz.is_empty() && msg.fill_sz != \"0\" {\n        parse_quantity(&msg.fill_sz, size_precision)\n            .map_err(|e| anyhow::anyhow!(\"Failed to parse fill_sz='{}': {e}\", msg.fill_sz,))?\n    } else if let Some(ref acc_fill_sz) = msg.acc_fill_sz {\n        // If fillSz is missing but accFillSz is available, calculate incremental fill\n        if !acc_fill_sz.is_empty() && acc_fill_sz != \"0\" {\n            let current_filled = parse_quantity(acc_fill_sz, size_precision).map_err(|e| {\n                anyhow::anyhow!(\"Failed to parse acc_fill_sz='{acc_fill_sz}': {e}\",)\n            })?;\n\n            // Calculate incremental fill as: current_total - previous_total\n            if let Some(prev_qty) = previous_filled_qty {\n                if current_filled < prev_qty {\n                    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!(","sourceCodeStart":2089,"sourceCodeEnd":2125,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/parse.rs#L2089-L2125","documentation":"For a regular OKX order fill, if the incremental fillSz is present and non-zero, it is used directly as the fill quantity. This error is thrown when parse_quantity fails on that fill_sz (invalid number, negative, or exceeding the instrument's size precision), so the fill report cannot be built.","triggerScenarios":"parse_fill_report receives an order update where fill_sz is non-empty and != \"0\" but parse_quantity(&msg.fill_sz, size_precision) errors — e.g. fractional digits beyond lotSz precision, negative value, or non-numeric string.","commonSituations":"Stale cached instrument definition with outdated lotSz after an OKX instrument parameter change; unexpected fill_sz like '0.000000001' on instruments with coarse lot sizes; malformed payload from an API schema change.","solutions":["Refresh the instrument definition (lotSz) so size_precision fits the received fill_sz.","Log the raw order message and verify fill_sz is numeric and non-negative.","Resync fills via OKX REST (fills endpoint) if the stream data is suspect.","Update adapter parsing if OKX changed the fillSz format."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Rust: pre-validate fill_sz against instrument precision\nfn fill_sz_ok(fill_sz: &str, precision: u32) -> bool {\n    !fill_sz.is_empty() && fill_sz != \"0\"\n        && rust_decimal::Decimal::from_str(fill_sz).map(|d| d.is_sign_positive() && d.scale() as u32 <= precision).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = parse_fill_report(&msg, ...) {\n    log::warn!(\"fill_sz parse failed for {}: {e}\", msg.inst_id);\n    resync_order_state(&msg.inst_id);\n}","preventionTips":["Sync instrument definitions on startup and on instrument-status changes.","Log raw payloads for any parse failure to detect API format changes early.","Pin and update the adapter to match OKX API revisions."],"tags":["parsing","okx","quantity","order-fill"],"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"}