nautechsystems/nautilus_trader · error

Python on_order_list failed: {e}

Error message

Python on_order_list failed: {e}

What it means

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.

Source

Thrown at crates/common/src/python/actor.rs:269

        if self.core.config.log_commands {
            let id = self.core.actor_id;
            log::info!("{id} {RECV}{CMD} {command}");
        }

        if self.core.state() != ComponentState::Running {
            return Ok(());
        }

        match command {
            TradingCommand::SubmitOrder(cmd) => {
                let order = DataActor::cache(self).try_order(&cmd.client_order_id)?;
                self.dispatch_on_order(order)
                    .map_err(|e| anyhow::anyhow!("Python on_order failed: {e}"))
            }
            TradingCommand::SubmitOrderList(cmd) => {
                let orders = self.orders_for_list(&cmd.order_list)?;
                self.dispatch_on_order_list(cmd.order_list.clone(), orders)
                    .map_err(|e| anyhow::anyhow!("Python on_order_list failed: {e}"))
            }
            _ => {
                log::warn!("Unhandled command type: {command}");
                Ok(())
            }
        }
    }

    fn orders_for_list(&self, order_list: &OrderList) -> anyhow::Result<Vec<OrderAny>> {
        let cache = DataActor::cache(self);
        let mut orders = Vec::with_capacity(order_list.client_order_ids.len());

        for client_order_id in &order_list.client_order_ids {
            orders.push(cache.try_order(client_order_id)?);
        }

        Ok(orders)
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained '{e}' cause for the original Python exception inside on_order_list
  2. Make on_order_list defensive: skip/handle orders missing from cache rather than assuming completeness
  3. Unit-test on_order_list with partially filled or partially denied order lists
  4. Update handler logic to the current order-list API if upgrading from an older Nautilus version

Example fix

# before
def on_order_list(self, order_list):
    total = sum(o.quantity for o in self.orders[o.order_list_id])  # KeyError
# after
def on_order_list(self, order_list):
    orders = self.orders.get(order_list.order_list_id, [])
    total = sum(o.quantity for o in orders)
    if not orders:
        self.log.warning("No cached orders for list")
        return
Defensive patterns

Strategy: try-catch

Validate before calling

def check_order_list_resolved(order_list) -> bool:
    cached = [self.cache.order(oid) for oid in order_list.order_ids()]
    return all(o is not None for o in cached) and len(cached) > 0

Type guard

def has_all_orders(self, order_list) -> bool:
    return all(
        self.cache.order(cid) is not None
        for cid in order_list.order_ids()
    )

Try / catch

def on_order_list(self, order_list):
    try:
        self._handle_order_list(order_list)
    except Exception as e:
        self.log.exception(f"on_order_list failed for {order_list.order_list_id}: {e}")

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ff08e4fc055168ac. Report an issue: GitHub.