{"record":{"id":"1cabd2f549d39234","repo":"nautechsystems/nautilus_trader","slug":"client-order-id-differs-across-fill-group","errorCode":null,"errorMessage":"client order ID differs across fill group","messagePattern":"client order ID differs across fill group","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/live/src/execution/manager.rs","lineNumber":1287,"sourceCode":"        };\n        let venue_position_id = first\n            .venue_position_id\n            .ok_or_else(|| anyhow::anyhow!(\"venue position ID is missing\"))?;\n\n        for fill in fills.iter().skip(1) {\n            anyhow::ensure!(\n                fill.account_id == first.account_id,\n                \"account ID differs across fill group\"\n            );\n            anyhow::ensure!(\n                fill.instrument_id == first.instrument_id,\n                \"instrument ID differs across fill group\"\n            );\n            anyhow::ensure!(\n                fill.venue_order_id == first.venue_order_id,\n                \"venue order ID differs across fill group\"\n            );\n            anyhow::ensure!(\n                fill.client_order_id == first.client_order_id,\n                \"client order ID differs across fill group\"\n            );\n            anyhow::ensure!(\n                fill.order_side == first.order_side,\n                \"order side differs across fill group\"\n            );\n            anyhow::ensure!(\n                fill.venue_position_id == first.venue_position_id,\n                \"venue position ID differs across fill group\"\n            );\n        }\n\n        anyhow::ensure!(\n            first.instrument_id == instrument.id(),\n            \"instrument metadata does not match fill group\"\n        );\n","sourceCodeStart":1269,"sourceCodeEnd":1305,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/execution/manager.rs#L1269-L1305","documentation":"create_orphan_fill_order_report collapses a group of FillReports into one synthetic OrderStatusReport, which requires a single client_order_id. This ensure! verifies all fills in the group share the same client_order_id; disagreement means the group mixes fills the trader cannot attribute to one client order, so the aggregation is aborted.","triggerScenarios":"FillReports grouped together during reconciliation (e.g. orphan fills for an external order) contain different client_order_id values — typically one fill has a client_order_id assigned by Nautilus and another has None or a venue-assigned value.","commonSituations":"Orders placed outside Nautilus and then partially reconciled, causing mixed ID attribution; adapter reporting some fills with a client order ID and others without (e.g. after a restart or an externally modified order); replayed fill data across sessions with different ID conventions.","solutions":["Verify all fills for the same venue order were submitted under the same client order ID; re-key the fill group so only fills with identical client_order_id are merged.","Check that your adapter assigns client_order_id deterministically (generate_order_status_reports / client ID resolution) rather than leaving it None for some fills.","If the order is fully external, ensure the adapter sets the same synthetic client order ID for every fill of that venue order.","Clear stale reconciliation/cache state (cached client order ID mappings) that may associate an old client order ID with the order."],"exampleFix":"// before: merged all fills for an instrument into one group\nlet group: Vec<&FillReport> = fills_by_instrument[&instrument_id].clone();\n// after: sub-group by client_order_id so IDs agree\nlet group: Vec<&FillReport> = fills_by_client_order_id[&client_order_id].clone();","handlingStrategy":"validation","validationCode":"let client_ids: std::collections::HashSet<_> = fills.iter().map(|f| f.client_order_id).collect();\nassert!(client_ids.len() == 1, \"fill group has mixed client order IDs: {:?}\", client_ids);","typeGuard":"fn single_client_order_group(fills: &[&FillReport]) -> bool {\n    fills.iter().all(|f| f.client_order_id == fills[0].client_order_id)\n}","tryCatchPattern":null,"preventionTips":["Use deterministic client order ID generation so every fill of an order reports the same client_order_id.","For fully external orders, ensure the adapter assigns one consistent synthetic client order ID per venue order.","Reconcile against a clean cache state; purge stale client-order-ID mappings after restarts or venue migrations."],"tags":["reconciliation","rust","client-order-id","invariant-violation"],"backgroundTag":"internal-invariant-violation","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"}