nautechsystems/nautilus_trader · error
Simulation module {module_index} {method} failed: {error:#}
Error message
Simulation module {module_index} {method} failed: {error:#} What it means
When a simulation module (aAct/act component attached to the exchange) raises an error during pre-processing or per-data processing, store_module_error wraps it with the module index and method name, stores it (the next module callback surfaces it via check_module_error), and returns the enriched error. It tells you exactly which module and phase failed.
Source
Thrown at crates/backtest/src/exchange.rs:349
anyhow::bail!("Simulation module failure requires exchange reset: {error}");
}
Ok(())
}
#[must_use]
pub(crate) const fn has_module_error(&self) -> bool {
self.module_error.is_some()
}
fn store_module_error(
&mut self,
module_index: usize,
method: &str,
error: &anyhow::Error,
) -> anyhow::Error {
let error = format!("Simulation module {module_index} {method} failed: {error:#}");
self.module_error = Some(error.clone());
anyhow::anyhow!(error)
}
fn pre_process_modules(&mut self, data: &Data) -> anyhow::Result<()> {
self.check_module_error()?;
for module_index in 0..self.modules.len() {
if let Err(e) = self.modules[module_index].pre_process(data) {
return Err(self.store_module_error(module_index, "pre_process", &e));
}
}
Ok(())
}
/// Returns the configured book type for this venue.
#[must_use]
pub const fn book_type(&self) -> BookType {
self.book_type
}View on GitHub (pinned to 18893faf8b)
Solutions
- Read the full chained message (the suffix after 'failed:') for the module's root cause.
- Inspect the module at the reported module_index (order of modules added to the exchange) and the reported method (pre_process vs process).
- Harden your custom module's process/pre_process against missing instruments/prices by returning controlled errors or skipping.
- Check the data stream for anomalies (gaps, zero prices) fed to the exchange before the module runs.
Example fix
// before
fn process(&mut self, data: &Data) -> anyhow::Result<()> {
let price = self.last_price(data.instrument_id()).unwrap(); // panics -> module error
Ok(())
}
// after
fn process(&mut self, data: &Data) -> anyhow::Result<()> {
let Some(price) = self.last_price(data.instrument_id()) else {
tracing::warn!("no price yet for {}; skipping", data.instrument_id());
return Ok(());
};
Ok(())
} Defensive patterns
Strategy: try-catch
Validate before calling
// keep custom module processing defensive
fn process(&mut self, data: &Data) -> anyhow::Result<()> {
self.state.required_context().ok_or_else(|| anyhow::anyhow!("module not initialized"))?;
Ok(())
} Try / catch
match result {
Err(e) if format!("{e:#}").starts_with("Simulation module") => {
// parse module_index and method from the message, log, then disable that module and retry
eprintln!("module failure: {e:#}");
}
other => other?,
} Prevention
- Make custom module methods total: handle missing instruments/prices gracefully instead of panicking.
- Keep the module list small and log the index at registration so failures are traceable.
- Test modules in isolation with representative data before attaching to a full backtest.
When it happens
Trigger: pre_process_modules or process_modules invoking module.pre_process(data)/module.process(data) (or similar) which returns Err for module at module_index; the wrapped message includes the original error chain via {error:#}.
Common situations: A custom user module panicking/erroring on unexpected data (None prices, missing instruments); a built-in module encountering data it cannot handle at the exchange level; module state corrupted after a prior failure.
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
- Cannot handle command: {command:?}
- Latency model should be initialized
- Execution client should be initialized
- Matching engine not found for instrument {order_instrument_i
- Matching engine not found for instrument {instrument_id}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8b5a603c61ad70dd.
Report an issue: GitHub.