{"record":{"id":"756afc97a5b39b47","repo":"nautechsystems/nautilus_trader","slug":"error","errorCode":null,"errorMessage":"{error}","messagePattern":"\\{error\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/engine.rs","lineNumber":694,"sourceCode":"    /// aligns its chunks to this boundary.\n    ///\n    /// Streaming workflow:\n    /// 1. Add initial data and strategies\n    /// 2. Loop: call `run(streaming=true)`, `clear_data()`, `add_data(next_batch)`\n    /// 3. After all batches: call `end()` to finalize\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the backtest encounters an unrecoverable state.\n    pub fn run(\n        &mut self,\n        start: Option<UnixNanos>,\n        end: Option<UnixNanos>,\n        run_config_id: Option<String>,\n        streaming: bool,\n    ) -> anyhow::Result<()> {\n        if let Some(error) = &self.funding_error {\n            anyhow::bail!(\"{error}\");\n        }\n        self.check_module_errors()?;\n\n        if let Err(e) = self.run_impl(start, end, run_config_id, streaming) {\n            if self.funding_error.is_some()\n                || self\n                    .venues\n                    .values()\n                    .any(|exchange| exchange.borrow().has_module_error())\n            {\n                self.abort_run();\n            }\n            return Err(e);\n        }\n\n        // Finalize on non-streaming runs, or when a shutdown was triggered\n        // at any point during the run (including the trailing settle, module,\n        // and flush callbacks that execute after the main data loop) so the","sourceCodeStart":676,"sourceCodeEnd":712,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/engine.rs#L676-L712","documentation":"run() refuses to start when a funding_rate error was captured earlier (self.funding_error is set), typically from an exchange module failing during funding settlement processing. The stored error is re-raised so the backtest never proceeds on a poisoned exchange state.","triggerScenarios":"Calling engine.run() after a prior run or module pass recorded a funding error, e.g. a funding-rate calculation failure on an exchange during processing.","commonSituations":"Reusing one BacktestEngine across multiple runs where the first failed with a funding issue; funding rate data malformed for the venue/account config.","solutions":["Inspect and fix the underlying funding error (reset the engine with engine.reset() after diagnosing)","Check funding rate data and SimulatedVenueConfig (funding rate settings) for the venue","Create a fresh BacktestEngine if the previous run poisoned its state"],"exampleFix":"// before\nengine.run()?;\n// after\nif engine_funding_error_occurred() {\n    engine.reset();\n}\nengine.run()?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match engine.run(start, end, run_config_id, streaming) {\n    Err(e) if engine_has_funding_error() => {\n        eprintln!(\"run blocked by prior funding error: {e}\");\n        engine.reset(); // after fixing funding data/config\n    }\n    other => other?,\n}","preventionTips":["Never reuse a BacktestEngine after a failed run without reset()","Validate funding rate data before running venues with funding enabled","Check run logs for funding settlement warnings from earlier iterations"],"tags":["backtest","funding-rate","poisoned-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-14T05:17:10.506Z"}