nautechsystems/nautilus_trader · error
Cannot start bar aggregation for {bar_type}
Error message
Cannot start bar aggregation for {bar_type} What it means
After creating a bar aggregator for the given bar type and request ID, the engine looks it up in the bar_aggregators map and fails if it is absent. This is an internal invariant check immediately following create_bar_aggregator_for_key, so hitting it means aggregator creation silently failed or the entry was evicted concurrently.
Source
Thrown at crates/data/src/engine/mod.rs:4917
);
Ok(())
}
fn start_bar_aggregator(
&mut self,
bar_type: BarType,
request_id: Option<UUID4>,
skip_first_non_full_bar: Option<bool>,
) -> anyhow::Result<()> {
let key = bar_aggregator_key(bar_type, request_id);
let bar_type_std = bar_type.standard();
self.create_bar_aggregator_for_key(bar_type, request_id, skip_first_non_full_bar)?;
let aggregator = self
.bar_aggregators
.get(&key)
.ok_or_else(|| anyhow::anyhow!("Cannot start bar aggregation for {bar_type}"))?
.clone();
let defer_subscription_activation = request_id.is_none()
&& aggregator.borrow().is_running()
&& !self.bar_aggregator_handlers.contains_key(&key);
if !self.bar_aggregator_handlers.contains_key(&key) {
// Subscribe to underlying data topics
let mut subscriptions = Vec::new();
if bar_type.is_composite() {
let topic = switchboard::get_bars_topic(bar_type.composite());
let handler = TypedHandler::new(BarBarHandler::new(&aggregator, bar_type_std));
msgbus::subscribe_bars(topic.into(), handler.clone(), None);
subscriptions.push(BarAggregatorSubscription::Bar { topic, handler });
} else if bar_type.spec().price_type == PriceType::Last {
let topic = switchboard::get_trades_topic(bar_type.instrument_id());
let handler = TypedHandler::new(BarTradeHandler::new(&aggregator, bar_type_std));
msgbus::subscribe_trades(View on GitHub (pinned to 18893faf8b)
Solutions
- Retry the subscription once — if transient concurrency caused the miss, a fresh call recreates the aggregator.
- Check for concurrent subscribe/stop calls on the same BarType (e.g. an unsubscribe racing the subscribe) and serialize them.
- Verify the aggregator key derivation (bar_aggregator_key) is consistent between creation and lookup; update to a version where creation and lookup share one key.
- File an issue with the bar_type and call stack — this indicates an engine bug rather than user error.
Defensive patterns
Strategy: retry
Validate before calling
if engine.is_subscribed_bars(&bar_type) {
// already active, skip create/start path
} Try / catch
match result {
Err(e) if e.to_string().contains("Cannot start bar aggregation") => {
// retry once after a short delay; else surface as engine bug
}
other => other?,
} Prevention
- Avoid concurrent subscribe/stop calls for the same BarType.
- Serialize data engine subscription lifecycle calls.
- Keep engine versions in sync across the deployment (creation/lookup invariant).
When it happens
Trigger: Calling start_bar_aggregation / subscribe_bars where create_bar_aggregator_for_key succeeded but self.bar_aggregators.get(&key) returns None — effectively an internal invariant violation in the aggregator registry.
Common situations: Race conditions between concurrent subscribe/stop calls on the same bar type; forked engine state where the creation path was patched; custom request_id handling causing key mismatch.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- RequestJoin must be handled by handle_request_join
- Cannot request aggregated bars: one of the aggregators in `b
- query_catalog_leg called with non-catalog-eligible variant {
- Cannot build empty catalog response for non-catalog-eligible
- Cannot start bar aggregation: no instrument found for {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/65254b342dc37743.
Report an issue: GitHub.