nautechsystems/nautilus_trader · error
Aggregation type {} not supported for time bars
Error message
Aggregation type {} not supported for time bars What it means
`get_time_bar_start` computes the aligned start timestamp for time-based bars. Its match handles the eight time aggregations; the `_ => panic!("Aggregation type {} not supported for time bars", spec.aggregation)` arm fires when the bar's aggregation is inherently non-time based, so no calendar-aligned start exists. This is called from timer setup (`start_timer_internal`) when registering time-bar aggregators.
Source
Thrown at crates/model/src/data/bar.rs:322
year = year
.checked_sub(step_i32)
.expect("year arithmetic underflow");
}
loop {
let next_year = year
.checked_add(step_i32)
.expect("year arithmetic overflow");
if year_start(next_year) > now {
break;
}
year = next_year;
}
year_start(year)
}
_ => panic!(
"Aggregation type {} not supported for time bars",
spec.aggregation
),
}
}
/// Finds the closest smaller time based on a daily time origin and period.
///
/// This function calculates the most recent time that is aligned with the given period
/// and is less than or equal to the current time.
fn find_closest_smaller_time(
now: Timestamp,
daily_time_origin: SignedDuration,
period: SignedDuration,
) -> Timestamp {
// Floor to start of day
let day_start = Offset::UTC
.to_timestamp(Offset::UTC.to_datetime(now).date().at(0, 0, 0, 0))View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the BarType/aggregation is time based (use `aggregation.is_time_based()`-style check or match on the enum) before computing a time bar start.
- Route tick/value bar types to their non-timer aggregation path instead of `start_timer_internal`.
- Fix the BarType string in config so the aggregation is a time-based variant.
Example fix
// before
let start = get_time_bar_start(now, &bar_type, origin); // panics for VALUE bars
// after
if !matches!(bar_type.spec().aggregation,
BarAggregation::Millisecond | BarAggregation::Second | BarAggregation::Minute
| BarAggregation::Hour | BarAggregation::Day | BarAggregation::Week
| BarAggregation::Month | BarAggregation::Year) {
anyhow::bail!("cannot compute time bar start for non-time aggregation");
}
let start = get_time_bar_start(now, &bar_type, origin); Defensive patterns
Strategy: validation
Validate before calling
# Python
TIME_AGGS = {BarAggregation.MILLISECOND, BarAggregation.SECOND, BarAggregation.MINUTE,
BarAggregation.HOUR, BarAggregation.DAY, BarAggregation.WEEK,
BarAggregation.MONTH, BarAggregation.YEAR}
assert bar_type.spec().aggregation in TIME_AGGS, "time bar start requires a time-based aggregation" Type guard
def is_time_based(a) -> bool:
from nautilus_trader.model.enums import BarAggregation
return a in {BarAggregation.MILLISECOND, BarAggregation.SECOND, BarAggregation.MINUTE,
BarAggregation.HOUR, BarAggregation.DAY, BarAggregation.WEEK,
BarAggregation.MONTH, BarAggregation.YEAR} Prevention
- Dispatch on aggregation kind before registering time-bar timers
- Validate bar type specs in strategy config before the engine starts
- Never route tick/value bar types through get_time_bar_start
When it happens
Trigger: Registering or starting a bar aggregator whose BarSpecification uses a non-time aggregation (Tick, Value) but a time-based start computation; misconfigured BarType strings like `EUR/USD.LAST-TICK` routed through the time-bar start path.
Common situations: Strategy configs mixing tick bars and time bars where the timer registration path doesn't dispatch on aggregation kind; custom adapter code calling `get_time_bar_start` for a bar type parsed from user config.
Related errors
- Aggregation not time based
- Timedelta not supported for aggregation type: {:?}
- `handle_bar` is not implemented for `{}`
- {e}
- Binance Futures does not support {a:?} aggregation
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6c72f36f9c267eba.
Report an issue: GitHub.