nautechsystems/nautilus_trader · error

Simulation module {module_index} log_diagnostics failed: {e:

Error message

Simulation module {module_index} log_diagnostics failed: {e:#}

What it means

log_diagnostics iterates all registered simulation modules and propagates any failure from a module's own log_diagnostics call, wrapping it with the failing module's index. The root cause is inside the specific module named in the message; this wrapper only identifies which module failed.

Source

Thrown at crates/backtest/src/exchange.rs:1724

        self.funding_settlements.clear();
        self.message_queue.clear();
        self.inflight_queue.clear();
        self.inflight_counter.clear();

        log::info!("Resetting exchange state");
        self.module_error = module_error;
        self.check_module_error()
    }

    /// Logs diagnostic information from all simulation modules.
    ///
    /// # Errors
    ///
    /// Returns an error if a simulation module cannot produce its diagnostics.
    pub fn log_diagnostics(&self) -> anyhow::Result<()> {
        for (module_index, module) in self.modules.iter().enumerate() {
            module.log_diagnostics().map_err(|e| {
                anyhow::anyhow!("Simulation module {module_index} log_diagnostics failed: {e:#}")
            })?;
        }
        Ok(())
    }

    /// Checks if any margin accounts have breached maintenance margin and liquidates open
    /// positions when the trigger threshold is met.
    ///
    /// Liquidation is scoped to the breached settlement currency: only positions whose
    /// instrument settles in the same currency as the breached margin account are closed.
    /// Positions settled in other currencies remain open, isolating the liquidation to
    /// the currency whose equity fell below the maintenance threshold.
    ///
    /// > **Note**: A future `cross_margin_mode` venue configuration could extend this to
    /// > liquidate all positions across all settlement currencies simultaneously.
    pub fn process_liquidations(&mut self, ts_now: UnixNanos) {
        if !self.liquidation_enabled {
            return;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the chained '{e:#}' detail in the message to find the module's underlying failure
  2. Ensure modules are fully initialized (e.g. first on_bar/on_event processing done) before calling log_diagnostics
  3. Wrap the call and treat diagnostics as best-effort: log and continue rather than aborting the backtest

Example fix

// before
engine.log_diagnostics()?;
// after
if let Err(e) = engine.log_diagnostics() {
    log::warn!("diagnostics unavailable: {e:#}");
}
Defensive patterns

Strategy: try-catch

Try / catch

// treat diagnostics as best-effort
if let Err(e) = engine.log_diagnostics() {
    log::warn!("diagnostics failed: {e:#");
}

Prevention

When it happens

Trigger: Calling SimulationEngine/Exchange log_diagnostics() when any registered simulation module (e.g. the CFD swap module) returns an error from its internal log_diagnostics implementation.

Common situations: Calling diagnostics on an engine whose modules are not yet initialized (e.g. CFD swap module before rollover day setup); running diagnostics mid-backtest when module internal state is transiently empty.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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