nautechsystems/nautilus_trader · error · anyhow::Error
Python on_historical_bars failed: {e}
Error message
Python on_historical_bars failed: {e} What it means
This error wraps any failure while the Rust engine invokes the strategy's Python `on_historical_bars` callback with a batch of Bar objects. Conversion of each Bar to a Python object or an exception raised inside the user's Python handler is captured and re-raised as `Python on_historical_bars failed: {e}`.
Source
Thrown at crates/trading/src/python/strategy.rs:1252
.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}"))
}
}
fn state_to_pydict(py: Python<'_>, state: &IndexMap<String, Vec<u8>>) -> PyResult<Py<PyDict>> {
let py_state = PyDict::new(py);View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the `{e}` message for the underlying Python exception raised in your `on_historical_bars` override and fix it.
- Confirm the override signature `def on_historical_bars(self, bars)` matches exactly.
- Handle the empty-bars case before processing.
- Check that any indicators or types used in the handler accept the Bar objects passed.
Example fix
// before
def on_historical_bars(self, bars):
self.fast.update(bars[-1])
// after
def on_historical_bars(self, bars):
if not bars:
return
for bar in bars:
self.fast.update(bar) Defensive patterns
Strategy: try-catch
Validate before calling
def _safe_on_historical_bars(self, bars):
if bars is None or len(bars) == 0:
return
assert all(hasattr(b, 'open') and hasattr(b, 'close') for b in bars) Type guard
def is_bar_list(obj):
return isinstance(obj, (list, tuple)) and all(hasattr(b, 'close') for b in obj) Try / catch
def on_historical_bars(self, bars):
try:
for bar in bars:
self.indicators.update(bar)
except Exception as e:
self.log.error(f'Failed processing historical bars: {e}', exc_info=True) Prevention
- Guard indicator updates against empty bar batches
- Keep the handler free of side effects that can raise (network, file I/O)
- Test strategies with empty historical responses before live runs
- Do not rename or shadow the on_historical_bars hook
When it happens
Trigger: Historical bar data (e.g. from a request_bars response) is delivered to a Python strategy whose `on_historical_bars` override raises, or whose bars fail the Rust→Python conversion.
Common situations: User handler assumes a specific bar count or bar fields; calling indicators with wrong types; exceptions like KeyError/TypeError in the override; requesting bars for an instrument with no data and mishandling the empty list.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Python on_bar failed: {e}
- Python on_bar failed: {e}
- Python on_degrade failed: {e}
- Python on_time_event failed: {e}
- Python on_data failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1e1a06938e72e254.
Report an issue: GitHub.