nautechsystems/nautilus_trader · error

Python on_reset failed: {e}

Error message

Python on_reset failed: {e}

What it means

Raised by the Rust `DataActor` bridge when the Python actor's `on_reset()` callback raises an exception. `dispatch_on_reset()` forwards to the Python method and any exception becomes this anyhow error. on_reset runs when returning a component to a fresh pre-start state.

Source

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

impl DataActor for PyDataActorInner {
    fn on_start(&mut self) -> anyhow::Result<()> {
        self.dispatch_on_start()
            .map_err(|e| anyhow::anyhow!("Python on_start failed: {e}"))
    }

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

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

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

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

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

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

    fn on_save(&self) -> anyhow::Result<IndexMap<String, Vec<u8>>> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the Python traceback inside the error to find the failing statement in on_reset.
  2. Use getattr/hasattr guards or initialize all resettable attributes in __init__ so reset never touches missing state.
  3. Avoid external I/O in on_reset; keep it to clearing in-memory state.
  4. Reproduce with a direct call: instantiate the actor, run on_start then on_reset under a test.

Example fix

// before (Python)
def on_reset(self):
    self.orders.clear()
    self.indicator.reset()

// after
def on_reset(self):
    self.orders.clear()
    if self.indicator is not None:
        self.indicator.reset()
Defensive patterns

Strategy: try-catch

Validate before calling

# verify all resettable attributes exist
missing = [a for a in ('orders', 'indicator') if not hasattr(self, a)]
assert not missing, f'on_reset would fail, missing attrs: {missing}'

Type guard

def safe_reset(obj, name):
    attr = getattr(obj, name, None)
    return attr.reset() if hasattr(attr, 'reset') else None

Try / catch

def on_reset(self):
    try:
        ...  # clear state
    except Exception as e:
        self.log.error(f"on_reset failed: {e}")

Prevention

When it happens

Trigger: Any exception thrown in the user's Python `on_reset`: calling reset on an object that is None, clearing collections that don't exist, or invoking external APIs during reset that fail.

Common situations: Backtest/kitchen-sink runs resetting strategies between iterations where reset code assumes live-only resources; AttributeError from resetting attributes that were only created conditionally in on_start.

Related errors


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