nautechsystems/nautilus_trader · error
Python SimulationModule.acknowledge failed: {e}
Error message
Python SimulationModule.acknowledge failed: {e} What it means
The Python SimulationModule's acknowledge method raised an exception when the exchange confirmed account adjustment outcomes (e.g. deposit/withdrawal results). The Rust wrapper maps the PyErr to this anyhow error.
Source
Thrown at crates/backtest/src/python/modules.rs:308
.extract::<Option<Vec<Money>>>()?;
Ok(adjustments.map_or(
SimulationModuleResult::NotReady,
SimulationModuleResult::Completed,
))
})
.map_err(|e| anyhow::anyhow!("Python SimulationModule.process failed: {e}"))
}
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}"))
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the exception shown in the Python traceback inside acknowledge.
- Make acknowledge idempotent/tolerant of unknown outcome IDs.
- Ensure reset() clears any per-adjustment state so acknowledgments stay in sync.
Example fix
# before
def acknowledge(self, outcomes):
for o in outcomes:
del self.pending[o.id] # KeyError
# after
def acknowledge(self, outcomes):
for o in outcomes:
self.pending.pop(o.id, None) Defensive patterns
Strategy: try-catch
Try / catch
def acknowledge(self, outcomes):
try:
for o in outcomes:
self.pending.pop(o.id, None)
except Exception:
logging.exception("acknowledge failed")
raise
Prevention
- Make acknowledge idempotent: tolerate unknown or already-acknowledged outcome IDs.
- Keep adjustment ledger state in sync by clearing it in reset().
- Test deposit/withdrawal acknowledgment flows explicitly in module unit tests.
When it happens
Trigger: Calling exchange acknowledge flows where the Python module's acknowledge(outcomes) raises: unexpected outcome types, state mismatch (acknowledging an adjustment the module doesn't track).
Common situations: Modules that maintain ledger state desynchronized with the engine (e.g. after a reset or replay); KeyError on the outcome ID.
Related errors
- Python SimulationModule.pre_process failed: {e}
- Python SimulationModule.process 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/85fd0f94f09ead9a.
Report an issue: GitHub.