nautechsystems/nautilus_trader · error

`step` overflows i64 days

Error message

`step` overflows i64 days

What it means

In `get_bar_interval` (crates/model/src/data/bar.rs:182), a Week aggregation multiplies the step by 7 days with `step.checked_mul(7).expect("`step` overflows i64 days")`. If `step` is large enough that step*7 exceeds i64, the checked multiplication returns None and the code panics. It is a deliberate arithmetic-overflow guard on user-supplied bar aggregation steps.

Source

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

/// Returns the bar interval as a [`SignedDuration`].
///
/// # Panics
///
/// Panics if the aggregation method of the given `bar_type` is not time based,
/// or if `step` is too large for the interval arithmetic.
#[must_use]
pub fn get_bar_interval(bar_type: &BarType) -> SignedDuration {
    let spec = bar_type.spec();
    let step = step_to_i64(spec.step);

    match spec.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!("Aggregation not time based"),
    }
}

/// Returns the bar interval as [`DurationNanos`].
///
/// # Panics
///
/// Panics if the aggregation method of the given `bar_type` is not time based.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use a sane step value: step is in units of the aggregation (days for Week), so keep step * 7 well within i64 (practically step << 1.3e18).
  2. Validate the step when building the BarType (reject steps above a practical maximum such as u32 range) before aggregation starts.
  3. Check where the BarType is constructed (config parse, Python binding) and clamp or reject oversized steps there.

Example fix

// before
let bar_type = BarType::new(instrument_id, BarAggregation::Week, 9_223_372_036_854_775_807, PriceType::Last);
// after
let step = 9_223_372_036_854_775_807;
assert!(step <= i64::MAX / 7, "week step too large");
let bar_type = BarType::new(instrument_id, BarAggregation::Week, step, PriceType::Last);
Defensive patterns

Strategy: validation

Validate before calling

// rust
fn week_step_ok(step: i64) -> bool { step > 0 && step <= i64::MAX / 7 }

Try / catch

// Panics are not catchable in Rust; validate before constructing the BarType.
if !week_step_ok(step) { return Err(BarConfigError::StepTooLarge(step)); }

Prevention

When it happens

Trigger: Calling `get_bar_interval`/`get_bar_interval_ns` with a `BarType` whose bar aggregation is Week and whose step value is near/above i64::MAX/7 (e.g. an absurdly large step parsed from configuration or an adversarial input).

Common situations: Mistyped aggregation step in a config file (e.g. a step in nanoseconds pasted where days were expected); programmatic construction of BarType with an unvalidated step; tests exercising the overflow path.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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