{"record":{"id":"a2278a6ca7fea0df","repo":"nautechsystems/nautilus_trader","slug":"simulation-module-failure-requires-exchange-reset","errorCode":null,"errorMessage":"Simulation module failure requires exchange reset: {error}","messagePattern":"Simulation module failure requires exchange reset: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/backtest/src/exchange.rs","lineNumber":331,"sourceCode":"\n    /// Sets the latency model for the exchange.\n    pub fn set_latency_model(&mut self, latency_model: LatencyModelHandle) {\n        self.latency_model = Some(latency_model);\n    }\n\n    #[must_use]\n    pub(crate) const fn has_modules(&self) -> bool {\n        !self.modules.is_empty()\n    }\n\n    #[must_use]\n    pub(crate) const fn liquidation_enabled(&self) -> bool {\n        self.liquidation_enabled\n    }\n\n    pub(crate) fn check_module_error(&self) -> anyhow::Result<()> {\n        if let Some(error) = &self.module_error {\n            anyhow::bail!(\"Simulation module failure requires exchange reset: {error}\");\n        }\n        Ok(())\n    }\n\n    #[must_use]\n    pub(crate) const fn has_module_error(&self) -> bool {\n        self.module_error.is_some()\n    }\n\n    fn store_module_error(\n        &mut self,\n        module_index: usize,\n        method: &str,\n        error: &anyhow::Error,\n    ) -> anyhow::Error {\n        let error = format!(\"Simulation module {module_index} {method} failed: {error:#}\");\n        self.module_error = Some(error.clone());\n        anyhow::anyhow!(error)","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/exchange.rs#L313-L349","documentation":"A simulation module (e.g. a funding or fee module) attached to the exchange reported an error during processing; the exchange marks itself with module_error and every subsequent check aborts, requiring the exchange to be reset before processing can continue. This prevents operating on an exchange whose module state is inconsistent.","triggerScenarios":"Any module hook raising during pre_process_modules, process_funding_settlement, process_modules, or reset; then a later check_module_error() call surfaces it.","commonSituations":"Funding rate calculation failure mid-backtest; module hitting invalid market state; reusing an exchange after a module fault without resetting.","solutions":["Reset the exchange (and engine) after fixing the module fault before continuing processing","Inspect the embedded module error message to find which simulation module failed and why","Validate module inputs (funding rates, fee models) that could raise mid-processing"],"exampleFix":"// before\nexchange.process(...)?; // fails: module error latched\n// after\nexchange.reset()?; // clears module_error after fixing the module fault\nexchange.process(...)?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = exchange.check_module_error() {\n    if e.to_string().starts_with(\"Simulation module failure requires exchange reset\") {\n        eprintln!(\"module fault: {e}; fixing and resetting exchange\");\n        exchange.reset()?;\n    }\n}","preventionTips":["Always reset() the exchange/engine after a module fault before further processing","Read the embedded error to identify which simulation module failed","Validate module inputs (funding rates, fee models) that can raise mid-simulation"],"tags":["backtest","simulation-module","exchange-state"],"backgroundTag":"invalid-state-transition","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"}