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
- Read the Python traceback inside the error to find the failing statement in on_reset.
- Use getattr/hasattr guards or initialize all resettable attributes in __init__ so reset never touches missing state.
- Avoid external I/O in on_reset; keep it to clearing in-memory state.
- 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
- Create every resettable attribute in __init__ so reset never sees missing state.
- Keep on_reset free of external I/O.
- Run reset in your test teardown so it is exercised on every test run.
- Use None checks before calling reset() on optional components.
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
- Python on_stop failed: {e}
- Python on_resume failed: {e}
- Python on_dispose failed: {e}
- Python on_degrade failed: {e}
- Python on_fault failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3f202315a79003db.
Report an issue: GitHub.