nautechsystems/nautilus_trader · error
Python SimulationModule.log_diagnostics failed: {e}
Error message
Python SimulationModule.log_diagnostics failed: {e} What it means
Calling the Python SimulationModule object's log_diagnostics method raised a Python exception; the Rust wrapper propagates it as an anyhow error so the backtest module diagnostics step fails with the underlying Python error message.
Source
Thrown at crates/backtest/src/python/modules.rs:316
fn acknowledge(&self, outcomes: &[AccountAdjustmentOutcome]) -> anyhow::Result<()> {
Python::attach(|py| -> anyhow::Result<()> {
let outcomes = outcomes
.iter()
.map(PyAccountAdjustmentOutcome::from)
.collect::<Vec<_>>();
self.obj.bind(py).call_method1("acknowledge", (outcomes,))?;
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()));
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the exception in the Python module's log_diagnostics per the traceback.
- Use getattr(..., default)/dict.get so diagnostics never fail on absent state.
- Wrap diagnostics formatting so it degrades gracefully when state is empty.
Example fix
# before
def log_diagnostics(self):
print(self.counts['ticks']) # KeyError
# after
def log_diagnostics(self):
print(self.counts.get('ticks', 0)) Defensive patterns
Strategy: try-catch
Try / catch
def log_diagnostics(self):
try:
print(self.counts.get('ticks', 0))
except Exception:
logging.exception("log_diagnostics failed") # never let diagnostics break the run
Prevention
- Diagnostics code must never raise: use .get()/getattr defaults everywhere.
- Format state defensively — assume any attribute may be unpopulated.
- Call log_diagnostics manually in tests to verify it is safe.
When it happens
Trigger: Engine diagnostics invocation (e.g. at halt/teardown or on request) where the Python module's log_diagnostics() raises, typically while formatting module state.
Common situations: Diagnostics code assuming internal attributes exist when they were never populated (e.g. empty books, missing counters) raising AttributeError/KeyError.
Related errors
- Python SimulationModule.pre_process failed: {e}
- Python SimulationModule.process failed: {e}
- Python SimulationModule.acknowledge failed: {e}
- Python SimulationModule.reset failed: {e}
- BacktestEngineConfig.controller for importable controller '{
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e876db3221e373b0.
Report an issue: GitHub.