nautechsystems/nautilus_trader · error

Python SimulationModule.reset failed: {e}

Error message

Python SimulationModule.reset failed: {e}

What it means

Calling the Python SimulationModule object's reset method raised a Python exception; the Rust wrapper propagates it as an anyhow error, so resetting the custom simulation module fails with the underlying Python error message.

Source

Thrown at crates/backtest/src/python/modules.rs:324

            Ok(())
        })
        .map_err(|e| anyhow::anyhow!("Python SimulationModule.acknowledge failed: {e}"))
    }

    fn log_diagnostics(&self) -> anyhow::Result<()> {
        Python::attach(|py| -> anyhow::Result<()> {
            self.obj.bind(py).call_method0("log_diagnostics")?;
            Ok(())
        })
        .map_err(|e| anyhow::anyhow!("Python SimulationModule.log_diagnostics failed: {e}"))
    }

    fn reset(&self) -> anyhow::Result<()> {
        Python::attach(|py| -> anyhow::Result<()> {
            self.obj.bind(py).call_method0("reset")?;
            Ok(())
        })
        .map_err(|e| anyhow::anyhow!("Python SimulationModule.reset failed: {e}"))
    }
}

fn pyobject_to_builtin_simulation_module_any(
    obj: &Bound<'_, PyAny>,
) -> Option<SimulationModuleAny> {
    if let Ok(module) = obj.extract::<PyRef<'_, CfdSwapModule>>() {
        return Some(SimulationModuleAny::CfdSwap((*module).clone()));
    }

    if let Ok(module) = obj.extract::<PyRef<'_, FXRolloverInterestModule>>() {
        return Some(SimulationModuleAny::FXRolloverInterest((*module).clone()));
    }
    None
}

/// Extracts a Python object into a declarative simulation module.
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the exception in the Python module's reset per the traceback.
  2. Make reset defensive: use del self.x if hasattr(self, 'x') or initialize defaults in __init__ and restore them in reset.
  3. Ensure __init__ creates every attribute that reset touches.

Example fix

# before
def reset(self):
    self.book.clear()
    self.book = None  # was never set before first run
# after
def __init__(self):
    self.book = {}
def reset(self):
    self.book = {}
Defensive patterns

Strategy: try-catch

Try / catch

def reset(self):
    try:
        self.book = {}
        self.counts = {}
    except Exception:
        logging.exception("reset failed")
        raise

Prevention

When it happens

Trigger: Calling node.reset() / engine reset where the Python module's reset() raises, typically because reset assumes state that was never initialized (accessing attributes before first process call).

Common situations: Running multiple iterations of a backtest where a module's reset references objects created lazily in process(); deleting keys that don't exist.

Related errors


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