nautechsystems/nautilus_trader · warning
Cannot stop bar aggregator: no aggregator to stop for {bar_t
Error message
Cannot stop bar aggregator: no aggregator to stop for {bar_type} What it means
stop_bar_aggregator removes the aggregator from the bar_aggregators map and stops it. If no aggregator is registered for the bar type (and request ID key), removal is impossible and the engine returns this error — the caller asked to stop aggregation that was never started or was already stopped.
Source
Thrown at crates/data/src/engine/mod.rs:5142
UUID4::new(),
cmd.ts_init,
Some(cmd.command_id),
cmd.params.clone(),
);
self.execute(DataCommand::Unsubscribe(UnsubscribeCommand::Quotes(
unsubscribe,
)));
}
}
fn stop_bar_aggregator(
&mut self,
bar_type: BarType,
request_id: Option<UUID4>,
) -> anyhow::Result<()> {
let key = bar_aggregator_key(bar_type, request_id);
let aggregator = self.bar_aggregators.shift_remove(&key).ok_or_else(|| {
anyhow::anyhow!("Cannot stop bar aggregator: no aggregator to stop for {bar_type}")
})?;
aggregator.borrow_mut().stop();
// Unsubscribe any registered message handlers
if let Some(subs) = self.bar_aggregator_handlers.remove(&key) {
for sub in subs {
match sub {
BarAggregatorSubscription::Bar { topic, handler } => {
msgbus::unsubscribe_bars(topic.into(), &handler);
}
BarAggregatorSubscription::Trade { topic, handler } => {
msgbus::unsubscribe_trades(topic.into(), &handler);
}
BarAggregatorSubscription::Quote { topic, handler } => {
msgbus::unsubscribe_quotes(topic.into(), &handler);
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Only call stop_bar_aggregator for bar types previously started; track subscribed bar types in the caller and skip unknown ones.
- Make teardown idempotent by checking subscription state (or catching this error and ignoring it) before stopping.
- Pass the exact same request_id (or None) used when the aggregation was started.
- If the aggregator should exist, check for a prior stop or cache/engine reset earlier in the run.
Example fix
// before
engine.stop_bar_aggregator(bar_type, request_id)?;
// after
if engine.is_subscribed_bars(&bar_type) {
engine.stop_bar_aggregator(bar_type, request_id)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
if engine.is_subscribed_bars(&bar_type) {
engine.stop_bar_aggregator(bar_type, request_id)?;
} Try / catch
match engine.stop_bar_aggregator(bar_type, request_id) {
Err(e) if e.to_string().contains("no aggregator to stop") => { /* already stopped: ignore */ }
other => other?,
} Prevention
- Make shutdown/teardown idempotent.
- Track active bar subscriptions and only stop those.
- Reuse the exact request_id from subscription time.
- Don't assume stop is safe on never-started bar types.
When it happens
Trigger: Calling unsubscribe_bars/stop_bar_aggregator for a BarType that was never subscribed, double-stopping the same bar type, or passing a request_id different from the one used at subscription time.
Common situations: Duplicate teardown in shutdown code; unsubscribing bars after the engine was reset; idempotent cleanup scripts assuming stop is a no-op; request_id mismatch making the key lookup miss.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot request aggregated bars: one of the aggregators in `b
- Cannot start bar aggregation: no instrument found for {}
- Cannot start bar aggregation for {bar_type}
- Cannot setup bar aggregator: no aggregator found for {bar_ty
- No live aggregator for continuous future subscription {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1e4f7ccf8fd2770b.
Report an issue: GitHub.