nautechsystems/nautilus_trader · error
Python SimulationModule.pre_process failed: {e}
Error message
Python SimulationModule.pre_process failed: {e} What it means
A Python-side SimulationModule's pre_process method raised an exception while the backtest exchange pre-processed incoming data. The Rust wrapper converts the resulting PyErr into an anyhow error prefixed with this message.
Source
Thrown at crates/backtest/src/python/modules.rs:276
impl PythonSimulationModule {
#[must_use]
pub const fn new(obj: Py<PyAny>) -> Self {
Self { obj }
}
pub(crate) fn clone_ref(&self, py: Python<'_>) -> Py<PyAny> {
self.obj.clone_ref(py)
}
}
impl SimulationModule for PythonSimulationModule {
fn pre_process(&self, data: &Data) -> anyhow::Result<()> {
Python::attach(|py| -> anyhow::Result<()> {
let data = data_to_pyobject(py, data.clone())?;
self.obj.bind(py).call_method1("pre_process", (data,))?;
Ok(())
})
.map_err(|e| anyhow::anyhow!("Python SimulationModule.pre_process failed: {e}"))
}
fn process(
&self,
ts_now: nautilus_core::UnixNanos,
ctx: &ExchangeContext,
) -> anyhow::Result<SimulationModuleResult> {
Python::attach(|py| -> anyhow::Result<SimulationModuleResult> {
let context = Py::new(py, PySimulationModuleContext::from_exchange(ctx))?;
let adjustments = self
.obj
.bind(py)
.call_method1("process", (ts_now.as_u64(), context))?
.extract::<Option<Vec<Money>>>()?;
Ok(adjustments.map_or(
SimulationModuleResult::NotReady,
SimulationModuleResult::Completed,
))View on GitHub (pinned to 18893faf8b)
Solutions
- Read the chained Python traceback in the error text and fix the exception in the Python module's pre_process method.
- Add defensive handling for the data types your module can receive (use isinstance checks on the converted data object).
- Test the module in isolation by calling pre_process with sample data before running the full backtest.
Example fix
# before
def pre_process(self, data):
return self.state[data.venue] # KeyError propagates
# after
def pre_process(self, data):
return self.state.get(data.venue, None) Defensive patterns
Strategy: try-catch
Validate before calling
module.pre_process(sample_data) # smoke-test with representative data before the backtest
Try / catch
class SafeModule(SimulationModule):
def pre_process(self, data):
try:
return self._pre_process(data)
except Exception:
logging.exception("SimulationModule.pre_process failed")
raise
Prevention
- Unit-test custom SimulationModules with representative data payloads before running full backtests.
- Handle None/unknown data types defensively inside pre_process.
- Log the chained Python traceback: the anyhow message embeds the original PyErr.
When it happens
Trigger: The Python object implementing SimulationModule.pre_process(data) raises any exception during the backtest data pipeline (buggy user code, bad data conversion, wrong data type handling in the module).
Common situations: User-authored simulation module assumptions broken by the data payload type; None handling errors; unhandled market-data formats in custom fill models or fee modules.
Related errors
- Python SimulationModule.process failed: {e}
- Python SimulationModule.acknowledge failed: {e}
- Python SimulationModule.log_diagnostics 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/2d0ebb28ac23d590.
Report an issue: GitHub.