nautechsystems/nautilus_trader · error

Python on_historical_bars failed: {e}

Error message

Python on_historical_bars failed: {e}

What it means

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.

Source

Thrown at crates/common/src/python/actor.rs:1246

            .map_err(|e| anyhow::anyhow!("Python on_historical_quotes failed: {e}"))
    }

    fn on_historical_trades(&mut self, trades: &[TradeTick]) -> anyhow::Result<()> {
        self.dispatch_on_historical_trades(trades.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_trades failed: {e}"))
    }

    fn on_historical_funding_rates(
        &mut self,
        funding_rates: &[FundingRateUpdate],
    ) -> anyhow::Result<()> {
        self.dispatch_on_historical_funding_rates(funding_rates.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_funding_rates failed: {e}"))
    }

    fn on_historical_bars(&mut self, bars: &[Bar]) -> anyhow::Result<()> {
        self.dispatch_on_historical_bars(bars.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_bars failed: {e}"))
    }

    fn on_historical_mark_prices(&mut self, mark_prices: &[MarkPriceUpdate]) -> anyhow::Result<()> {
        self.dispatch_on_historical_mark_prices(mark_prices.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_mark_prices failed: {e}"))
    }

    fn on_historical_index_prices(
        &mut self,
        index_prices: &[IndexPriceUpdate],
    ) -> anyhow::Result<()> {
        self.dispatch_on_historical_index_prices(index_prices.to_vec())
            .map_err(|e| anyhow::anyhow!("Python on_historical_index_prices failed: {e}"))
    }
}

#[pymethods]
#[pyo3_stub_gen::derive::gen_stub_pymethods]

View on GitHub (pinned to 18893faf8b)

Solutions

  1. 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`.
  2. Verify your Python actor actually defines `on_historical_bars` with the expected signature and does not shadow it with an incompatible override.
  3. Validate bar data (non-empty, correct Bar type, expected instrument IDs) before replaying historical data.
  4. Run the handler logic standalone in Python with the same bars to reproduce and debug the exception quickly.

Example fix

// Python side — before (fragile handler)
def on_historical_bars(self, bars):
    closes = [b.close for b in bars]
    avg = sum(closes) / len(closes)  # ZeroDivisionError if bars is empty

// after
def on_historical_bars(self, bars):
    if not bars:
        return
    closes = [b.close for b in bars]
    avg = sum(closes) / len(closes)
Defensive patterns

Strategy: try-catch

Validate before calling

# Python
assert callable(getattr(actor, 'on_historical_bars', None)), 'actor missing on_historical_bars'
assert bars, 'no bars to replay'

Type guard

def has_bar_handler(actor) -> bool:
    return callable(getattr(actor, 'on_historical_bars', None))

Try / catch

match actor.on_historical_bars(bars) {
    Err(e) => { log::error!("historical bars dispatch failed: {e:#}"); /* halt replay or skip actor */ }
    Ok(()) => {}
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/c80df83aa938fe51. Report an issue: GitHub.