nautechsystems/nautilus_trader · critical

`handle_depth` {IMPL_ERR} `{}`

Error message

`handle_depth` {IMPL_ERR} `{}`

What it means

Default `Indicator::handle_depth` panics when an indicator is given an `OrderBookDepth10` snapshot without overriding `handle_depth`. The trait's default body is a guard panic: depth-10 book input requires explicit indicator support, and reaching the default means the indicator was subscribed to depth data it cannot process. The message renders as "`handle_depth` is not implemented for `<indicator name>`".

Source

Thrown at crates/indicators/src/indicator.rs:44

#[allow(unused_variables)]
pub trait Indicator {
    fn name(&self) -> String;

    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());
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Override `fn handle_depth(&mut self, depth: &OrderBookDepth10)` in the indicator impl to consume depth snapshots.
  2. Change the market data subscription to a type the indicator supports (quotes, trades, or deltas).
  3. Filter depth events before dispatch so only depth-capable indicators receive them.

Example fix

// before
// subscription emits OrderBookDepth10 into an indicator without handle_depth

// after
impl Indicator for MyIndicator {
    fn handle_depth(&mut self, depth: &OrderBookDepth10) {
        // aggregate top-N levels into the indicator's update
    }
}
Defensive patterns

Strategy: validation

Validate before calling

assert!(matches!(ind.data_types(), DataType::Quotes | DataType::Deltas) == false || depth_disabled, "indicator cannot consume OrderBookDepth10");

Try / catch

// guard before dispatch: if depth_capable(ind) { ind.handle_depth(depth); } else { log::warn!("skipping depth for {}", ind.name()); }

Prevention

When it happens

Trigger: Calling `handle_depth(&OrderBookDepth10)` on an indicator that does not override it — e.g. subscribing a bar- or quote-based indicator to a depth-10 market data stream, or an engine that fans depth snapshots out to all registered indicators.

Common situations: Configuring a data client to emit OrderBookDepth10 (depth=10 subscription) while indicators in the pipeline only handle quotes/trades; custom indicators where the depth method was skipped; switching a subscription from deltas to depth without updating indicator code.

Related errors


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