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

  1. Fix the exception in the Python module's log_diagnostics per the traceback.
  2. Use getattr(..., default)/dict.get so diagnostics never fail on absent state.
  3. 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

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


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