nautechsystems/nautilus_trader · error

Python on_order_list failed: {e}

Error message

Python on_order_list failed: {e}

What it means

When the Python object overrides `on_order_list`, PyExecutionAlgorithm dispatches the whole list into Python via `dispatch_on_order_list`; any Python exception is re-wrapped as this anyhow error. If there is no override, Rust falls back to looping on_order per order instead.

Source

Thrown at crates/trading/src/python/algorithm.rs:407

impl ExecutionAlgorithm for PyExecutionAlgorithm {
    fn on_order(&mut self, order: OrderAny) -> anyhow::Result<()> {
        self.dispatch_on_order(order)
            .map_err(|e| anyhow::anyhow!("Python on_order failed: {e}"))
    }

    fn on_order_list(
        &mut self,
        order_list: OrderList,
        orders: Vec<OrderAny>,
    ) -> anyhow::Result<()> {
        if self
            .has_python_override("on_order_list")
            .map_err(|e| anyhow::anyhow!("Python override lookup failed: {e}"))?
        {
            return self
                .dispatch_on_order_list(order_list, orders)
                .map_err(|e| anyhow::anyhow!("Python on_order_list failed: {e}"));
        }

        for order in orders {
            self.on_order(order)?;
        }
        Ok(())
    }

    fn on_start(&mut self) -> anyhow::Result<()> {
        log::info!("Starting {}", self.exec_algorithm_id());
        Ok(())
    }

    fn on_stop(&mut self) -> anyhow::Result<()> {
        Ok(())
    }

    fn on_reset(&mut self) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the chained `{e}` traceback and fix the Python on_order_list implementation.
  2. Verify the Python signature matches dispatch_on_order_list's expected (order_list, orders) layout.
  3. Test the batch callback with the same OrderList/OrderAny contents in pure Python to reproduce.
  4. If batch handling is not needed, remove the on_order_list override so the Rust per-order fallback runs.

Example fix

// before
def on_order_list(self, orders): ...  # wrong signature

// after
def on_order_list(self, order_list, orders): ...
Defensive patterns

Strategy: try-catch

Validate before calling

# Python: verify batch signature before registration
import inspect
sig = inspect.signature(algo.on_order_list)
assert len(sig.parameters) == 2, "on_order_list must take (order_list, orders)"

Try / catch

match algo.on_order_list(order_list, orders) {
    Ok(()) => {},
    Err(e) => log::error!("python on_order_list failed: {e:#}"),
}

Prevention

When it happens

Trigger: Python class defines on_order_list and it raises when called with the OrderList plus orders — bad signature, exception in user code, or argument conversion failure (OrderList/orders to Python).

Common situations: User Python on_order_list assumes a different tuple/argument layout; conversion of an order in the list fails mid-iteration; a domain exception inside the batch handler.

Related errors


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