{"record":{"id":"82a6ae344d803ac2","repo":"nautechsystems/nautilus_trader","slug":"orderlist-from-orders-requires-non-empty-orders","errorCode":null,"errorMessage":"OrderList::from_orders requires non-empty orders","messagePattern":"OrderList::from_orders requires non-empty orders","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/orders/list.rs","lineNumber":125,"sourceCode":"    /// the list may target different instruments at the same venue.\n    /// Callers in the production path (`OrderFactory` plus a single\n    /// strategy instance) produce orders with a consistent `order_list_id`\n    /// and `strategy_id`. [`OrderList::validate`] checks the syntactic\n    /// invariants (non-empty, unique `client_order_ids`); it does not\n    /// check cross-field consistency.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `orders` is empty, if the first order has no\n    /// `order_list_id`, or if orders span more than one venue. Callers\n    /// are expected to guard non-empty input; `Strategy::submit_order_list`\n    /// filters out the empty case and bails on mixed venues before\n    /// reaching this constructor.\n    #[must_use]\n    pub fn from_orders(orders: &[OrderAny], ts_init: UnixNanos) -> Self {\n        let first = orders\n            .first()\n            .expect(\"OrderList::from_orders requires non-empty orders\");\n        let order_list_id = first\n            .order_list_id()\n            .expect(\"OrderList::from_orders requires first order to have order_list_id\");\n        let instrument_id = first.instrument_id();\n        let strategy_id = first.strategy_id();\n        let venue = instrument_id.venue;\n\n        for order in orders {\n            assert!(\n                order.instrument_id().venue == venue,\n                \"OrderList::from_orders requires all orders to share the same venue; \\\n                 expected {venue}, found {} on {}\",\n                order.instrument_id().venue,\n                order.client_order_id(),\n            );\n        }\n\n        let client_order_ids = orders.iter().map(Order::client_order_id).collect();","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/orders/list.rs#L107-L143","documentation":"OrderList::from_orders constructs an OrderList from a slice of orders and needs a first order to derive the list id, instrument, and venue. It panics when given an empty slice; the doc comment notes callers are expected to filter out the empty case upstream.","triggerScenarios":"Calling OrderList::from_orders(&[], ts_init) — e.g. building order lists from a batch that produced zero orders.","commonSituations":"Batching submitted orders per venue where a filter (time-in-force, price checks) removed all orders; strategies submitting after a cancel-all emptied the pending buffer; feeding an empty container from Python-side code.","solutions":["Check !orders.is_empty() (or after filtering) before calling from_orders","Return early / skip list construction entirely when no orders remain","Route empty batches through a different path that does not require an OrderList"],"exampleFix":"// before\nlet list = OrderList::from_orders(&pending, ts_init);\n// after\nif pending.is_empty() {\n    return Ok(None);\n}\nlet list = OrderList::from_orders(&pending, ts_init);","handlingStrategy":"validation","validationCode":"// Rust\nif orders.is_empty() { return Ok(None); } // before from_orders\nlet list = OrderList::from_orders(orders, ts_init);","typeGuard":"fn non_empty(orders: &[OrderAny]) -> Option<&[OrderAny]> { if orders.is_empty() { None } else { Some(orders) } }","tryCatchPattern":null,"preventionTips":["Filter batches first, then skip OrderList construction when nothing remains","Centralize submission batching in one function that owns the empty check","Add debug_assert!(!orders.is_empty()) in callers that feed from_orders"],"tags":["rust","panic","orders","empty-input"],"backgroundTag":"empty-required-field","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"}