{"record":{"id":"c80df83aa938fe51","repo":"nautechsystems/nautilus_trader","slug":"python-on-historical-bars-failed-e","errorCode":null,"errorMessage":"Python on_historical_bars failed: {e}","messagePattern":"Python on_historical_bars failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/python/actor.rs","lineNumber":1246,"sourceCode":"            .map_err(|e| anyhow::anyhow!(\"Python on_historical_quotes failed: {e}\"))\n    }\n\n    fn on_historical_trades(&mut self, trades: &[TradeTick]) -> anyhow::Result<()> {\n        self.dispatch_on_historical_trades(trades.to_vec())\n            .map_err(|e| anyhow::anyhow!(\"Python on_historical_trades failed: {e}\"))\n    }\n\n    fn on_historical_funding_rates(\n        &mut self,\n        funding_rates: &[FundingRateUpdate],\n    ) -> anyhow::Result<()> {\n        self.dispatch_on_historical_funding_rates(funding_rates.to_vec())\n            .map_err(|e| anyhow::anyhow!(\"Python on_historical_funding_rates failed: {e}\"))\n    }\n\n    fn on_historical_bars(&mut self, bars: &[Bar]) -> anyhow::Result<()> {\n        self.dispatch_on_historical_bars(bars.to_vec())\n            .map_err(|e| anyhow::anyhow!(\"Python on_historical_bars failed: {e}\"))\n    }\n\n    fn on_historical_mark_prices(&mut self, mark_prices: &[MarkPriceUpdate]) -> anyhow::Result<()> {\n        self.dispatch_on_historical_mark_prices(mark_prices.to_vec())\n            .map_err(|e| anyhow::anyhow!(\"Python on_historical_mark_prices failed: {e}\"))\n    }\n\n    fn on_historical_index_prices(\n        &mut self,\n        index_prices: &[IndexPriceUpdate],\n    ) -> anyhow::Result<()> {\n        self.dispatch_on_historical_index_prices(index_prices.to_vec())\n            .map_err(|e| anyhow::anyhow!(\"Python on_historical_index_prices failed: {e}\"))\n    }\n}\n\n#[pymethods]\n#[pyo3_stub_gen::derive::gen_stub_pymethods]","sourceCodeStart":1228,"sourceCodeEnd":1264,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/python/actor.rs#L1228-L1264","documentation":"This error wraps any failure raised by a Python data actor's `on_historical_bars` callback when the Rust actor core dispatches historical bars into Python. It is a bridging error: the Rust side succeeded in collecting the bars, but the Python handler (or something it calls) raised an exception, which is converted into an anyhow error with this prefix.","triggerScenarios":"Calling the actor's historical-data dispatch path (e.g. via `PyDataActor::on_historical_bars` in crates/common/src/python/actor.rs:1246) when the registered Python object's `on_historical_bars` method raises an exception — bad bar data assumptions, unhandled None, a bug in user Python code, or a missing/renamed callback method.","commonSituations":"Backtesting or historical-data replay where a user-defined Python strategy actor processes `Bar` objects and its handler contains a Python bug (attribute error, division by zero, incompatible indicator input), or the callback was renamed/overridden incorrectly in a subclass.","solutions":["Read the full chained error message: the `{e}` portion contains the original Python traceback/exception; fix the bug it reports in your Python actor's `on_historical_bars`.","Verify your Python actor actually defines `on_historical_bars` with the expected signature and does not shadow it with an incompatible override.","Validate bar data (non-empty, correct Bar type, expected instrument IDs) before replaying historical data.","Run the handler logic standalone in Python with the same bars to reproduce and debug the exception quickly."],"exampleFix":"// Python side — before (fragile handler)\ndef on_historical_bars(self, bars):\n    closes = [b.close for b in bars]\n    avg = sum(closes) / len(closes)  # ZeroDivisionError if bars is empty\n\n// after\ndef on_historical_bars(self, bars):\n    if not bars:\n        return\n    closes = [b.close for b in bars]\n    avg = sum(closes) / len(closes)","handlingStrategy":"try-catch","validationCode":"# Python\nassert callable(getattr(actor, 'on_historical_bars', None)), 'actor missing on_historical_bars'\nassert bars, 'no bars to replay'","typeGuard":"def has_bar_handler(actor) -> bool:\n    return callable(getattr(actor, 'on_historical_bars', None))","tryCatchPattern":"match actor.on_historical_bars(bars) {\n    Err(e) => { log::error!(\"historical bars dispatch failed: {e:#}\"); /* halt replay or skip actor */ }\n    Ok(()) => {}\n}","preventionTips":["Keep Python handler code exception-free by validating inputs at the top of each handler","Test actors in pure Python against sample bars before Rust integration","Never shadow built-in callbacks with incompatible signatures"],"tags":["python","rust-bridge","actor","historical-data","callback"],"backgroundTag":"api-request-failed","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"}