nautechsystems/nautilus_trader · error

Timedelta not supported for aggregation type: {:?}

Error message

Timedelta not supported for aggregation type: {:?}

What it means

`BarType::timedelta` (and its Python wrapper) returns the bar interval as a timedelta duration. Like `get_bar_interval`, it only supports the time-based aggregations; the `_ => panic!("Timedelta not supported for aggregation type: {:?}", self.aggregation)` arm fires for non-time aggregations such as Tick or Value. Called via `bar_close_from_open`, `py_timedelta`, and `py_get_interval_ns`.

Source

Thrown at crates/model/src/data/bar.rs:587

        match self.aggregation {
            BarAggregation::Millisecond => SignedDuration::from_millis(step),
            BarAggregation::Second => SignedDuration::from_secs(step),
            BarAggregation::Minute => SignedDuration::from_mins(step),
            BarAggregation::Hour => SignedDuration::from_hours(step),
            BarAggregation::Day => duration_days(step),
            BarAggregation::Week => {
                duration_days(step.checked_mul(7).expect("`step` overflows i64 days"))
            }
            BarAggregation::Month => {
                // Proxy for comparing bar lengths
                duration_days(step.checked_mul(30).expect("`step` overflows i64 days"))
            }
            BarAggregation::Year => {
                // Proxy for comparing bar lengths
                duration_days(step.checked_mul(365).expect("`step` overflows i64 days"))
            }
            _ => panic!(
                "Timedelta not supported for aggregation type: {:?}",
                self.aggregation
            ),
        }
    }

    /// Return a value indicating whether the aggregation method is time-driven:
    ///  - [`BarAggregation::Millisecond`]
    ///  - [`BarAggregation::Second`]
    ///  - [`BarAggregation::Minute`]
    ///  - [`BarAggregation::Hour`]
    ///  - [`BarAggregation::Day`]
    ///  - [`BarAggregation::Week`]
    ///  - [`BarAggregation::Month`]
    ///  - [`BarAggregation::Year`]
    #[must_use]
    pub fn is_time_aggregated(&self) -> bool {
        matches!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the aggregation is time based before calling `timedelta()`.
  2. Handle tick/value bar types separately (they close on events, not on a time interval).
  3. Fix the BarType aggregation in your config/spec so it matches the time-interval expectation.

Example fix

# before
interval = bar_type.timedelta()  # panics for TICK bars

# after
from nautilus_trader.model.enums import BarAggregation
TIME_BASED = {BarAggregation.MILLISECOND, BarAggregation.SECOND, BarAggregation.MINUTE,
              BarAggregation.HOUR, BarAggregation.DAY, BarAggregation.WEEK,
              BarAggregation.MONTH, BarAggregation.YEAR}
if bar_type.spec().aggregation not in TIME_BASED:
    raise ValueError(f"no timedelta for {bar_type.spec().aggregation}")
interval = bar_type.timedelta()
Defensive patterns

Strategy: validation

Validate before calling

# Python
if bar_type.spec().aggregation in (BarAggregation.TICK, BarAggregation.VALUE):
    raise ValueError("timedelta only defined for time-based bar aggregations")
interval = bar_type.timedelta()

Type guard

def has_timedelta(bar_type) -> bool:
    a = bar_type.spec().aggregation
    from nautilus_trader.model.enums import BarAggregation
    return a not in (BarAggregation.TICK, BarAggregation.VALUE)

Prevention

When it happens

Trigger: Calling `bar_type.timedelta()` (or `py_get_interval_ns` from Python) on a BarType whose aggregation is TICK or VALUE; computing bar close times generically over a list of bar types that includes tick/value bars.

Common situations: Python strategy code calling `.timedelta` on tick bars to compute close times; mixed bar-type dashboards; instrument configs where the aggregation was changed from SECOND to TICK but downstream code still asks for a timedelta.

Related errors


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