{"record":{"id":"2676443e1b27b050","repo":"nautechsystems/nautilus_trader","slug":"non-empty-fill-group","errorCode":null,"errorMessage":"non-empty fill group","messagePattern":"non-empty fill group","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/execution/manager.rs","lineNumber":1342,"sourceCode":"                Ok::<_, anyhow::Error>((quantity, notional))\n            },\n        )?;\n\n        anyhow::ensure!(\n            quantity > Decimal::ZERO,\n            \"fill group quantity is not positive\"\n        );\n\n        let order_qty = Quantity::from_decimal_dp(quantity, instrument.size_precision())?;\n        let avg_px = notional\n            .checked_div(quantity)\n            .ok_or_else(|| anyhow::anyhow!(\"fill group average price is not representable\"))?;\n\n        let ts_accepted = fills\n            .iter()\n            .map(|fill| fill.ts_event)\n            .min()\n            .expect(\"non-empty fill group\");\n\n        let ts_last = fills\n            .iter()\n            .map(|fill| fill.ts_event)\n            .max()\n            .expect(\"non-empty fill group\");\n\n        let ts_init = fills\n            .iter()\n            .map(|fill| fill.ts_init)\n            .max()\n            .expect(\"non-empty fill group\");\n\n        let report = OrderStatusReport::new(\n            first.account_id,\n            first.instrument_id,\n            first.client_order_id,\n            first.venue_order_id,","sourceCodeStart":1324,"sourceCodeEnd":1360,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/execution/manager.rs#L1324-L1360","documentation":"When synthesizing an `OrderStatusReport` from a group of fills, the live execution manager computes the earliest fill timestamp with `fills.iter().map(...).min().expect(\"non-empty fill group\")`. `Iterator::min` returns `None` for an empty iterator, so the `.expect` panics. The invariant is that every caller passes at least one fill; hitting this panic means that assumption was violated.","triggerScenarios":"Reaching the report-building code with an empty `fills` collection — e.g. an `OrderStatusReport` generated during reconciliation or `generate_order_status_reports` where a matched fill group was filtered/deduplicated down to zero elements.","commonSituations":"Custom reconciliation logic passing empty fill vectors; an upstream filter removing all fills of a group; a venue status response containing zero fills while the code still attempts report construction.","solutions":["Guard the call site: bail or return early when `fills.is_empty()` before constructing the report","Replace the `expect` with `ok_or_else` + `?` so an empty group yields a handled error instead of a panic","Log the instrument_id/client_order_id that produced the empty group to find the upstream filter dropping fills","Review dedup/skip logic in fill-group construction for over-aggressive removal"],"exampleFix":"// before\nlet ts_accepted = fills.iter().map(|f| f.ts_event).min().expect(\"non-empty fill group\");\n// after\nanyhow::ensure!(!fills.is_empty(), \"cannot build OrderStatusReport from empty fill group\");\nlet ts_accepted = fills.iter().map(|f| f.ts_event).min().unwrap();","handlingStrategy":"type-guard","validationCode":"if fills.is_empty() {\n    return Err(anyhow::anyhow!(\"empty fill group; cannot build OrderStatusReport\"));\n}","typeGuard":"fn non_empty(fills: &[OrderFillReport]) -> Option<&[OrderFillReport]> {\n    (!fills.is_empty()).then_some(fills)\n}","tryCatchPattern":"match result_of_report_build { Ok(r) => r, Err(e) => log::error!(\"report build failed: {e}\") }","preventionTips":["Never call the report builder with a filtered collection without re-checking emptiness","Assert group non-emptiness right after fill-group construction","Log upstream filters that remove fills to catch over-filtering early"],"tags":["panic","invariant","reconciliation"],"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"}