{"record":{"id":"445ca445a7f49c24","repo":"nautechsystems/nautilus_trader","slug":"handle-bar-is-not-implemented-for","errorCode":null,"errorMessage":"`handle_bar` is not implemented for `{}`","messagePattern":"`handle_bar` is not implemented for `(.+?)`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/indicators/src/indicator.rs","lineNumber":65,"sourceCode":"    fn handle_book(&mut self, book: &OrderBook) {\n        panic!(\"`handle_book_mbo` {IMPL_ERR} `{}`\", self.name());\n    }\n\n    /// Updates the indicator with the given quote tick.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the configured price type cannot be extracted from the quote.\n    fn handle_quote(&mut self, quote: &QuoteTick) -> anyhow::Result<()> {\n        anyhow::bail!(\"`handle_quote_tick` {IMPL_ERR} `{}`\", self.name());\n    }\n\n    fn handle_trade(&mut self, trade: &TradeTick) {\n        panic!(\"`handle_trade_tick` {IMPL_ERR} `{}`\", self.name());\n    }\n\n    fn handle_bar(&mut self, bar: &Bar) {\n        panic!(\"`handle_bar` {IMPL_ERR} `{}`\", self.name());\n    }\n\n    fn reset(&mut self);\n}\n\npub trait MovingAverage: Indicator {\n    fn value(&self) -> f64;\n    fn count(&self) -> usize;\n    fn update_raw(&mut self, value: f64);\n}\n\nimpl Debug for dyn Indicator + Send {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        // Implement custom formatting for the Indicator trait object\n        write!(f, \"Indicator {{ ... }}\")\n    }\n}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/indicators/src/indicator.rs#L47-L83","documentation":"Default `Indicator::handle_bar` panics when an indicator receives a `Bar` without overriding `handle_bar`. The default body is a guard panic rendering \"`handle_bar` is not implemented for `<indicator name>`\". Bars are an aggregated data type; an indicator must explicitly opt into bar input, so reaching the default indicates the indicator was handed data it does not support.","triggerScenarios":"Calling `handle_bar(&Bar)` on a tick-based indicator (one implementing handle_quote/handle_trade but not handle_bar) — e.g. aggregating ticks into bars and then pushing the bars into all indicators, or a bar-based strategy using an indicator that only processes ticks.","commonSituations":"Switching a strategy from tick data to bar data without swapping indicators; bar aggregation pipelines dispatching finished bars to every registered indicator; custom indicators forgetting the bar override.","solutions":["Override `fn handle_bar(&mut self, bar: &Bar)` in the indicator impl to update from bar open/high/low/close.","Feed the indicator raw ticks instead of bars, or select an indicator variant that supports bars.","Adjust subscriptions so only bar-capable indicators receive Bar events."],"exampleFix":"// before\nimpl Indicator for TickOnlyIndicator { /* no handle_bar */ }\n\n// after\nimpl Indicator for TickOnlyIndicator {\n    fn handle_bar(&mut self, bar: &Bar) {\n        self.update_from_price(bar.close());\n    }\n}","handlingStrategy":"validation","validationCode":"assert!(ind.accepts(DataType::Bar), \"{} has no handle_bar impl\", ind.name());","typeGuard":null,"tryCatchPattern":"// guard: if bar_capable(ind) { ind.handle_bar(bar); } else { log::debug!(\"{} skips bars\", ind.name()); }","preventionTips":["When switching a strategy between tick and bar data, swap the indicator set accordingly.","Do not broadcast finished bars to every indicator; dispatch only to bar-capable ones.","Add a smoke test that runs the aggregator + indicators end to end."],"tags":["rust","panic","indicators","bars","missing-override"],"backgroundTag":"method-not-implemented","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"}