pola-rs/polars · error

out-of-range duration

Error message

out-of-range duration

What it means

Panics inside duration_s_to_duration: Duration::try_seconds returns None when the i64 seconds count exceeds chrono Duration's capacity (durations are capped at i64 milliseconds), i.e. |v| > i64::MAX/1000, and the infallible wrapper .expect panics.

Source

Thrown at crates/polars-arrow/src/temporal_conversions.rs:79

        .expect("invalid or out-of-range datetime")
}

/// converts a `i64` representing a `date64` to [`NaiveDate`]
#[inline]
pub fn date64_to_date(milliseconds: i64) -> NaiveDate {
    date64_to_datetime(milliseconds).date()
}

/// converts a `i32` representing a `time32(s)` to [`NaiveTime`]
#[inline]
pub fn time32s_to_time(v: i32) -> NaiveTime {
    NaiveTime::from_num_seconds_from_midnight_opt(v as u32, 0).expect("invalid time")
}

/// converts a `i64` representing a `duration(s)` to [`Duration`]
#[inline]
pub fn duration_s_to_duration(v: i64) -> Duration {
    Duration::try_seconds(v).expect("out-of-range duration")
}

/// converts a `i64` representing a `duration(ms)` to [`Duration`]
#[inline]
pub fn duration_ms_to_duration(v: i64) -> Duration {
    Duration::try_milliseconds(v).expect("out-of-range in duration conversion")
}

/// converts a `i64` representing a `duration(us)` to [`Duration`]
#[inline]
pub fn duration_us_to_duration(v: i64) -> Duration {
    Duration::microseconds(v)
}

/// converts a `i64` representing a `duration(ns)` to [`Duration`]
#[inline]
pub fn duration_ns_to_duration(v: i64) -> Duration {
    Duration::nanoseconds(v)

View on GitHub (pinned to df599052da)

Solutions

  1. Range-check: require |v| <= 9_223_372_036_854_775 before converting
  2. Null out or clip out-of-range values
  3. Fix the producer so the duration column carries seconds
  4. Handle the Option from Duration::try_seconds directly instead of the panicking helper

Example fix

// before
let d = duration_s_to_duration(v); // panics on |v| > i64::MAX/1000

// after
let d = Duration::try_seconds(v) // Option<Duration>
    .unwrap_or_default(); // or map to null
Defensive patterns

Strategy: validation

Validate before calling

fn duration_s_valid(v: i64) -> bool {
    v.unsigned_abs() <= (i64::MAX / 1000) as u64 // chrono caps at i64 ms
}

Type guard

fn is_valid_duration_s(v: i64) -> bool {
    v.unsigned_abs() <= (i64::MAX / 1000) as u64
}

Prevention

When it happens

Trigger: Converting duration(s) arrow values whose magnitude is astronomically large - sentinels like i64::MIN/MAX or wrong-unit data (nanosecond deltas stored in a seconds column).

Common situations: Unit mixups when producing arrow duration arrays; corrupt numeric columns; sentinel-filled buffers read as durations.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/af035c4dc21f80c3. Report an issue: GitHub.