nautechsystems/nautilus_trader · critical
`handle_book_mbo` {IMPL_ERR} `{}`
Error message
`handle_book_mbo` {IMPL_ERR} `{}` What it means
Default `Indicator::handle_book` panics when an indicator receives an MBO `OrderBook` object without overriding `handle_book`. Note the message string itself says "`handle_book_mbo` is not implemented for ..." (a known label inconsistency in the source): the method name is `handle_book` but the panic text references the MBO handler name. Either way, the default body is a guard: MBO (market-by-order) book input requires a dedicated override.
Source
Thrown at crates/indicators/src/indicator.rs:48
fn has_inputs(&self) -> bool;
fn initialized(&self) -> bool;
fn handle_delta(&mut self, delta: &OrderBookDelta) {
panic!("`handle_delta` {IMPL_ERR} `{}`", self.name());
}
fn handle_deltas(&mut self, deltas: &OrderBookDeltas) {
panic!("`handle_deltas` {IMPL_ERR} `{}`", self.name());
}
fn handle_depth(&mut self, depth: &OrderBookDepth10) {
panic!("`handle_depth` {IMPL_ERR} `{}`", self.name());
}
fn handle_book(&mut self, book: &OrderBook) {
panic!("`handle_book_mbo` {IMPL_ERR} `{}`", self.name());
}
/// Updates the indicator with the given quote tick.
///
/// # Errors
///
/// Returns an error if the configured price type cannot be extracted from the quote.
fn handle_quote(&mut self, quote: &QuoteTick) -> anyhow::Result<()> {
anyhow::bail!("`handle_quote_tick` {IMPL_ERR} `{}`", self.name());
}
fn handle_trade(&mut self, trade: &TradeTick) {
panic!("`handle_trade_tick` {IMPL_ERR} `{}`", self.name());
}
fn handle_bar(&mut self, bar: &Bar) {
panic!("`handle_bar` {IMPL_ERR} `{}`", self.name());
}View on GitHub (pinned to 18893faf8b)
Solutions
- Override `fn handle_book(&mut self, book: &OrderBook)` in the indicator impl to process the MBO book.
- Convert MBO books to a supported representation (e.g. deltas or depth) before passing to the indicator.
- Only register the indicator with data sources whose book type it actually implements.
Example fix
// before
// MBO OrderBook routed to indicator without handle_book
// after
impl Indicator for MyIndicator {
fn handle_book(&mut self, book: &OrderBook) {
// derive price/volume state from the MBO book
}
} Defensive patterns
Strategy: validation
Validate before calling
// ensure MBO sources are only wired to MBO-capable indicators
if book.is_mbo() && !ind.handles_mbo() { log::error!("{} cannot consume MBO book", ind.name()); return; } Try / catch
// guard the dispatch: if mbo_capable(ind) { ind.handle_book(book); } else { convert_book_to_deltas(book, &mut ind); } Prevention
- Only subscribe MBO data (e.g. Databento MBO) when indicators implement handle_book.
- Centralize book-type conversion (MBO -> deltas/depth) in one adapter.
- Note the message says handle_book_mbo though the method is handle_book — search for both names when diagnosing.
When it happens
Trigger: Calling `handle_book(&OrderBook)` on an indicator lacking an override — typically when MBO market data (e.g. from venues that publish market-by-order) is routed to an indicator implemented for quotes, trades, or deltas only.
Common situations: Subscribing indicators to MBO data feeds (DepthMarketData like Databento MBO); venue/data-source changes switching the book representation to MBO without updating indicator implementations; generic dispatch code that calls handle_book on every indicator in a registry.
Related errors
- `handle_delta` {IMPL_ERR} `{}`
- `handle_deltas` {IMPL_ERR} `{}`
- `handle_depth` {IMPL_ERR} `{}`
- `handle_trade_tick` is not implemented for `{}`
- `handle_bar` is not implemented for `{}`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/27a3c9e5a8655e6e.
Report an issue: GitHub.