nautechsystems/nautilus_trader · error
Cannot setup bar aggregator: no aggregator found for {bar_ty
Error message
Cannot setup bar aggregator: no aggregator found for {bar_type} What it means
setup_bar_aggregator requires an already-created aggregator in the bar_aggregators map for the given BarType/key. This function only configures (historical mode, handler, sequence validation) an existing aggregator; it never creates one. If none exists, the caller invoked setup out of order.
Source
Thrown at crates/data/src/engine/mod.rs:5051
);
return Some(SubscribeCommand::Quotes(subscribe));
}
None
}
/// Sets up a bar aggregator.
///
/// This method handles historical mode, message bus subscriptions, and time bar aggregator setup.
fn setup_bar_aggregator(
&self,
bar_type: BarType,
historical: bool,
request_id: Option<UUID4>,
) -> anyhow::Result<()> {
let key = bar_aggregator_key(bar_type, request_id);
let aggregator = self.bar_aggregators.get(&key).ok_or_else(|| {
anyhow::anyhow!("Cannot setup bar aggregator: no aggregator found for {bar_type}")
})?;
// Set historical mode and handler
let cache = self.cache.clone();
let validate_sequence = self.config.validate_data_sequence;
let publish = !historical;
let handler: Box<dyn FnMut(Bar)> = Box::new(move |bar: Bar| {
process_engine_bar(&cache, validate_sequence, publish, bar);
});
aggregator
.borrow_mut()
.set_historical_mode(historical, handler);
// For TimeBarAggregator, set clock and start timer
if bar_type.spec().is_time_aggregated() {
use nautilus_common::clock::TestClock;
View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure start_bar_aggregation (or the create step) is called for the bar_type before setup_bar_aggregator.
- Check that the same request_id is passed to both creation and setup — a None vs Some(UUID4) mismatch changes the key.
- If the aggregator was stopped, recreate it via start_bar_aggregation rather than re-running setup.
- Inspect bar_aggregators keys (via debug logging) to confirm the expected key exists.
Example fix
// before engine.setup_bar_aggregator(bar_type, historical, request_id); // after engine.start_bar_aggregation(bar_type, None, false)?; engine.setup_bar_aggregator(bar_type, historical, request_id)?;
Defensive patterns
Strategy: validation
Validate before calling
// ensure aggregation was started before setup engine.start_bar_aggregation(bar_type, None, false)?; engine.setup_bar_aggregator(bar_type, historical, request_id)?;
Prevention
- Follow create -> setup -> use ordering for aggregator lifecycle.
- Never call setup after stop; recreate instead.
- Use identical request_id values across lifecycle calls.
- Track per-bar-type lifecycle state in application code.
When it happens
Trigger: Calling setup_bar_aggregator (internal, from subscribe_bars handler wiring or replay paths) before start_bar_aggregation/create_bar_aggregator_for_key ran, or after stop_bar_aggregator removed the entry, or with a request_id that doesn't match the one used at creation.
Common situations: Replay/backtest code paths setting up aggregation twice; calling stop then setup on the same bar type; mismatched request_id between create and setup calls.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 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 stop bar aggregator: no aggregator to stop for {bar_t
- No live aggregator for continuous future subscription {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8522e720eacc57f3.
Report an issue: GitHub.