nautechsystems/nautilus_trader · error
Python on_order failed: {e}
Error message
Python on_order failed: {e} What it means
DataActor command execution wraps the Python on_order callback; any exception raised inside the user's Python on_order handler is converted into this anyhow error by execute_exec_algorithm_command. It means the exec algorithm's Python-level order-submission handler failed, aborting the SubmitOrder trading command.
Source
Thrown at crates/common/src/python/actor.rs:264
}
#[expect(clippy::needless_pass_by_ref_mut)]
impl PyDataActorInner {
fn execute_exec_algorithm_command(&mut self, command: &TradingCommand) -> anyhow::Result<()> {
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 {View on GitHub (pinned to 18893faf8b)
Solutions
- Read the chained '{e}' cause to find the underlying Python exception and fix the on_order handler
- Guard on_order with checks that the order and its instrument exist in cache before use
- Test the exec algorithm with a backtest covering submit-order paths before live use
- Log and handle expected edge cases (e.g. denied/canceled orders) inside on_order instead of raising
Example fix
# before
def on_order(self, order):
instrument = self.cache.instrument(order.instrument_id)
price = instrument.make_price(self.limit) # raises if instrument is None
# after
def on_order(self, order):
instrument = self.cache.instrument(order.instrument_id)
if instrument is None:
self.log.error(f"No instrument for {order.instrument_id}")
return
price = instrument.make_price(self.limit) Defensive patterns
Strategy: try-catch
Validate before calling
def check_order_ready(order) -> bool:
return (
order is not None
and self.cache.instrument(order.instrument_id) is not None
and order.client_order_id is not None
) Type guard
def order_in_cache(self, order) -> bool:
return self.cache.order(order.client_order_id) is not None Try / catch
def on_order(self, order):
try:
self._handle_order(order)
except Exception as e:
self.log.exception(f"on_order failed for {order.client_order_id}: {e}")
# do not re-raise unless the actor must halt Prevention
- Always handle None instruments/missing cache entries in on_order
- Log inside handlers so failures carry context beyond the generic wrapper message
- Backtest the exec algorithm's order paths before live use
- Keep on_order lightweight; defer heavy work to timers
When it happens
Trigger: An exec algorithm command TradingCommand::SubmitOrder is executed and the actor's dispatch_on_order invokes the Python on_order override, which raises an exception (bad attribute, missing cache data, invalid order state, Python bug).
Common situations: User-defined on_order in a Python exec algorithm references an attribute not yet initialized, handles orders whose instrument is missing from cache, or throws on None/odd order states during live reconciliation.
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
- Python on_order_list failed: {e}
- Python on_signal failed: {e}
- Python on_queue_state failed: {e}
- Python on_socket_state failed: {e}
- Python on_instrument failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c8c81a9a1fa2a6ef.
Report an issue: GitHub.