{"record":{"id":"85fd0f94f09ead9a","repo":"nautechsystems/nautilus_trader","slug":"python-simulationmodule-acknowledge-failed-e","errorCode":null,"errorMessage":"Python SimulationModule.acknowledge failed: {e}","messagePattern":"Python SimulationModule\\.acknowledge failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/python/modules.rs","lineNumber":308,"sourceCode":"                .extract::<Option<Vec<Money>>>()?;\n            Ok(adjustments.map_or(\n                SimulationModuleResult::NotReady,\n                SimulationModuleResult::Completed,\n            ))\n        })\n        .map_err(|e| anyhow::anyhow!(\"Python SimulationModule.process failed: {e}\"))\n    }\n\n    fn acknowledge(&self, outcomes: &[AccountAdjustmentOutcome]) -> anyhow::Result<()> {\n        Python::attach(|py| -> anyhow::Result<()> {\n            let outcomes = outcomes\n                .iter()\n                .map(PyAccountAdjustmentOutcome::from)\n                .collect::<Vec<_>>();\n            self.obj.bind(py).call_method1(\"acknowledge\", (outcomes,))?;\n            Ok(())\n        })\n        .map_err(|e| anyhow::anyhow!(\"Python SimulationModule.acknowledge failed: {e}\"))\n    }\n\n    fn log_diagnostics(&self) -> anyhow::Result<()> {\n        Python::attach(|py| -> anyhow::Result<()> {\n            self.obj.bind(py).call_method0(\"log_diagnostics\")?;\n            Ok(())\n        })\n        .map_err(|e| anyhow::anyhow!(\"Python SimulationModule.log_diagnostics failed: {e}\"))\n    }\n\n    fn reset(&self) -> anyhow::Result<()> {\n        Python::attach(|py| -> anyhow::Result<()> {\n            self.obj.bind(py).call_method0(\"reset\")?;\n            Ok(())\n        })\n        .map_err(|e| anyhow::anyhow!(\"Python SimulationModule.reset failed: {e}\"))\n    }\n}","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/python/modules.rs#L290-L326","documentation":"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.","triggerScenarios":"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).","commonSituations":"Modules that maintain ledger state desynchronized with the engine (e.g. after a reset or replay); KeyError on the outcome ID.","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."],"exampleFix":"# before\ndef acknowledge(self, outcomes):\n    for o in outcomes:\n        del self.pending[o.id]  # KeyError\n# after\ndef acknowledge(self, outcomes):\n    for o in outcomes:\n        self.pending.pop(o.id, None)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"def acknowledge(self, outcomes):\n    try:\n        for o in outcomes:\n            self.pending.pop(o.id, None)\n    except Exception:\n        logging.exception(\"acknowledge failed\")\n        raise\n","preventionTips":["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."],"tags":["python","backtest","simulation-module","callback"],"backgroundTag":"upstream-api-error","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}