{"record":{"id":"ff08e4fc055168ac","repo":"nautechsystems/nautilus_trader","slug":"python-on-order-list-failed-e","errorCode":null,"errorMessage":"Python on_order_list failed: {e}","messagePattern":"Python on_order_list failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/python/actor.rs","lineNumber":269,"sourceCode":"        if self.core.config.log_commands {\n            let id = self.core.actor_id;\n            log::info!(\"{id} {RECV}{CMD} {command}\");\n        }\n\n        if self.core.state() != ComponentState::Running {\n            return Ok(());\n        }\n\n        match command {\n            TradingCommand::SubmitOrder(cmd) => {\n                let order = DataActor::cache(self).try_order(&cmd.client_order_id)?;\n                self.dispatch_on_order(order)\n                    .map_err(|e| anyhow::anyhow!(\"Python on_order failed: {e}\"))\n            }\n            TradingCommand::SubmitOrderList(cmd) => {\n                let orders = self.orders_for_list(&cmd.order_list)?;\n                self.dispatch_on_order_list(cmd.order_list.clone(), orders)\n                    .map_err(|e| anyhow::anyhow!(\"Python on_order_list failed: {e}\"))\n            }\n            _ => {\n                log::warn!(\"Unhandled command type: {command}\");\n                Ok(())\n            }\n        }\n    }\n\n    fn orders_for_list(&self, order_list: &OrderList) -> anyhow::Result<Vec<OrderAny>> {\n        let cache = DataActor::cache(self);\n        let mut orders = Vec::with_capacity(order_list.client_order_ids.len());\n\n        for client_order_id in &order_list.client_order_ids {\n            orders.push(cache.try_order(client_order_id)?);\n        }\n\n        Ok(orders)\n    }","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/python/actor.rs#L251-L287","documentation":"DataActor command execution wraps the Python on_order_list callback; an exception raised inside the user's Python on_order_list handler is converted into this anyhow error by execute_exec_algorithm_command. It means the exec algorithm failed while processing a submitted order list, aborting the SubmitOrderList command.","triggerScenarios":"TradingCommand::SubmitOrderList is executed, orders_for_list resolves the list's orders from cache, and dispatch_on_order_list invokes the Python on_order_list override which raises (e.g. index/attribute errors, missing order in the resolved set).","commonSituations":"Python exec algorithm assumes all orders of an order list are present or in a specific state, divides by quantity sums that can be zero, or was written for a single order and mishandles list input after a version change.","solutions":["Inspect the chained '{e}' cause for the original Python exception inside on_order_list","Make on_order_list defensive: skip/handle orders missing from cache rather than assuming completeness","Unit-test on_order_list with partially filled or partially denied order lists","Update handler logic to the current order-list API if upgrading from an older Nautilus version"],"exampleFix":"# before\ndef on_order_list(self, order_list):\n    total = sum(o.quantity for o in self.orders[o.order_list_id])  # KeyError\n# after\ndef on_order_list(self, order_list):\n    orders = self.orders.get(order_list.order_list_id, [])\n    total = sum(o.quantity for o in orders)\n    if not orders:\n        self.log.warning(\"No cached orders for list\")\n        return","handlingStrategy":"try-catch","validationCode":"def check_order_list_resolved(order_list) -> bool:\n    cached = [self.cache.order(oid) for oid in order_list.order_ids()]\n    return all(o is not None for o in cached) and len(cached) > 0","typeGuard":"def has_all_orders(self, order_list) -> bool:\n    return all(\n        self.cache.order(cid) is not None\n        for cid in order_list.order_ids()\n    )","tryCatchPattern":"def on_order_list(self, order_list):\n    try:\n        self._handle_order_list(order_list)\n    except Exception as e:\n        self.log.exception(f\"on_order_list failed for {order_list.order_list_id}: {e}\")","preventionTips":["Never assume every order in a list is cached or filled; filter defensively","Write unit tests for partial fills, denials, and cancels within order lists","Avoid stateful assumptions (dicts keyed by list id) that break when lists arrive out of order","Keep list-handling logic independent of list size"],"tags":["python","actor","exec-algorithm","callback"],"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"}