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

  1. Only call stop_bar_aggregator for bar types previously started; track subscribed bar types in the caller and skip unknown ones.
  2. Make teardown idempotent by checking subscription state (or catching this error and ignoring it) before stopping.
  3. Pass the exact same request_id (or None) used when the aggregation was started.
  4. 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

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


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