nautechsystems/nautilus_trader · error

Python on_fault failed: {e}

Error message

Python on_fault failed: {e}

What it means

This error is raised by the Rust-side `ExecutionAlgorithm` wrapper when the Python callback `on_fault` throws an exception. NautilusTrader dispatches lifecycle hooks from Rust into the user's Python subclass via `call_method0`; any `PyErr` is wrapped with `anyhow!("Python on_fault failed: {e}")` so the trader kernel receives a Rust `anyhow::Error`. The original Python traceback is preserved inside `{e}`.

Source

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

    fn on_reset(&mut self) -> anyhow::Result<()> {
        ExecutionAlgorithm::on_reset(self)?;
        self.dispatch_no_args("on_reset")
            .map_err(|e| anyhow::anyhow!("Python on_reset failed: {e}"))
    }

    fn on_dispose(&mut self) -> anyhow::Result<()> {
        self.dispatch_no_args("on_dispose")
            .map_err(|e| anyhow::anyhow!("Python on_dispose failed: {e}"))
    }

    fn on_degrade(&mut self) -> anyhow::Result<()> {
        self.dispatch_no_args("on_degrade")
            .map_err(|e| anyhow::anyhow!("Python on_degrade failed: {e}"))
    }

    fn on_fault(&mut self) -> anyhow::Result<()> {
        self.dispatch_no_args("on_fault")
            .map_err(|e| anyhow::anyhow!("Python on_fault failed: {e}"))
    }

    fn on_time_event(&mut self, event: &TimeEvent) -> anyhow::Result<()> {
        ExecutionAlgorithm::on_time_event(self, event)?;
        self.dispatch_time_event(event)
            .map_err(|e| anyhow::anyhow!("Python on_time_event failed: {e}"))
    }

    fn on_signal(&mut self, signal: &Signal) -> anyhow::Result<()> {
        self.dispatch_on_signal(signal)
            .map_err(|e| anyhow::anyhow!("Python on_signal failed: {e}"))
    }

    fn on_queue_state(&mut self, event: &QueueStateChanged) -> anyhow::Result<()> {
        self.dispatch_on_queue_state(event)
            .map_err(|e| anyhow::anyhow!("Python on_queue_state failed: {e}"))
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the chained Python traceback inside the error message to find the real exception raised in your `on_fault` override
  2. Wrap the body of your Python `on_fault` in try/except for recoverable conditions and log instead of raising
  3. Fix the underlying bug in `on_fault` (wrong attribute name, wrong call signature, unhandled state)
  4. Verify the method signature matches the base class: `def on_fault(self) -> None:` (no extra args)
  5. Pin your nautilus_trader version and check the changelog for callback API changes if a signature mismatch appears after upgrading

Example fix

# before
def on_fault(self):
    self._orders[self._order_id].cancel()  # raises KeyError

# after
def on_fault(self):
    try:
        self._orders[self._order_id].cancel()
    except Exception as e:
        self.log.error(f"Fault recovery failed: {e}")
Defensive patterns

Strategy: try-catch

Validate before calling

import inspect
assert isinstance(getattr(MyAlgo, 'on_fault', None), (types.FunctionType, types.MethodType))
sig = inspect.signature(MyAlgo.on_fault)
assert len(sig.parameters) == 1  # self only

Type guard

def has_valid_on_fault(algo):
    fn = getattr(algo, 'on_fault', None)
    return callable(fn) and inspect.signature(fn).parameters.get('event') is None

Try / catch

try:
    algo.on_fault()
except Exception as e:
    log.error(f"Algorithm on_fault dispatch failed: {e}")  # original Python traceback is in str(e)

Prevention

When it happens

Trigger: Calling `on_fault()` on a `PyExecutionAlgorithm` (e.g. via the trader moving the algorithm into the FAULTED state, or a direct `algo.on_fault()` call) when the user's Python subclass overrides `on_fault` and raises any exception (AttributeError, TypeError, unhandled data error, etc.).

Common situations: Custom execution algorithms whose `on_fault` handler references attributes not yet initialized, calls an API with the wrong signature after a nautilus_trader version upgrade, or performs fault recovery logic (e.g. cancelling orders) that fails because the client/connection is already down.

Related errors


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