{"record":{"id":"4670c021e8c04faa","repo":"nautechsystems/nautilus_trader","slug":"orderfactory-create-list-requires-non-empty-order","errorCode":null,"errorMessage":"OrderFactory::create_list requires non-empty orders","messagePattern":"OrderFactory::create_list requires non-empty orders","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/factories/order.rs","lineNumber":1092,"sourceCode":"\n    /// Creates a new [`OrderList`] from the given orders, generating a fresh\n    /// order list ID and propagating it back to each order.\n    ///\n    /// All orders must share the same venue; the caller is responsible for\n    /// passing orders with the factory's `strategy_id`. The returned list's\n    /// invariants are checked by [`OrderList::validate`] at submission time.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `orders` is empty or if orders span more than one venue.\n    /// Callers are expected to guard non-empty input; `Strategy::submit_order_list`\n    /// filters out the empty case and bails on mixed venues before reaching\n    /// this constructor.\n    #[must_use]\n    pub fn create_list(&mut self, orders: &mut [OrderAny], ts_init: UnixNanos) -> OrderList {\n        let instrument_id = orders\n            .first()\n            .expect(\"OrderFactory::create_list requires non-empty orders\")\n            .instrument_id();\n        let venue = instrument_id.venue;\n\n        for order in orders.iter() {\n            assert!(\n                order.instrument_id().venue == venue,\n                \"OrderFactory::create_list 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 order_list_id = self.generate_order_list_id();\n        let order_ids: Vec<ClientOrderId> = orders.iter().map(OrderAny::client_order_id).collect();\n\n        for order in orders.iter_mut() {\n            order.set_order_list_id(order_list_id);","sourceCodeStart":1074,"sourceCodeEnd":1110,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/factories/order.rs#L1074-L1110","documentation":"OrderFactory::create_list builds an OrderList from a slice of orders and derives the shared instrument_id/venue from the first order. It panics when the slice is empty; the public wrapper filters out empty input and mixed venues before reaching this constructor, so hitting it means the guard was bypassed.","triggerScenarios":"Calling create_list with an empty orders slice directly (or via a path that skips the emptiness check), then reading orders.first() -> None -> panic.","commonSituations":"Building order lists from a dynamically filtered collection that ended up empty (e.g. all orders filtered out); tests constructing lists directly; upstream code passing Vec::new().","solutions":["Check !orders.is_empty() before calling create_list","Filter upstream so empty lists short-circuit and return an empty/None result instead","If mixing venues is possible, group orders by venue first (create_list also asserts a single venue)","Prefer the public wrapper that documents the empty-case filtering"],"exampleFix":"// before\nlet list = factory.create_list(&mut orders, ts_init);\n// after\nassert!(!orders.is_empty(), \"no orders to submit\");\nlet list = factory.create_list(&mut orders, ts_init);","handlingStrategy":"validation","validationCode":"if orders.is_empty() {\n    return Ok(OrderList::default()); // or early-return your own error\n}\nlet venue = orders[0].instrument_id().venue;\nif orders.iter().any(|o| o.instrument_id().venue != venue) {\n    return Err(\"mixed venues in create_list input\".into());\n}","typeGuard":"fn non_empty(orders: &[OrderAny]) -> Option<&[OrderAny]> {\n    if orders.is_empty() { None } else { Some(orders) }\n}","tryCatchPattern":"// Panic is not catchable; guard before the call\nassert!(!orders.is_empty(), \"create_list requires at least one order\");\nlet list = factory.create_list(&mut orders, ts_init);","preventionTips":["Early-return on empty order collections after filtering","Group orders by venue before building an OrderList (single venue required)","Centralize order-list construction so the emptiness check lives in one place"],"tags":["rust","panic","order-factory","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-14T00:17:10.932Z"}