pola-rs/polars · error · ValueError

invalid interval unit for time_range: found {unit!r}

Error message

invalid interval unit for time_range: found {unit!r}

What it means

Raised by polars.time_range when the interval string contains a date-scale unit ('y', 'mo', 'w' or 'd'). The time dtype has no date component, so intervals of days or larger are meaningless for it; only sub-day units (h, m, s, ms, us, ns) are valid.

Source

Thrown at py-polars/src/polars/functions/range/time_range.py:137

    >>> pl.time_range(
    ...     start=time(14, 0),
    ...     interval=timedelta(hours=3, minutes=15),
    ...     eager=True,
    ... ).alias("time")
    shape: (4,)
    Series: 'time' [time]
    [
        14:00:00
        17:15:00
        20:30:00
        23:45:00
    ]
    """
    interval = parse_interval_argument(interval)
    for unit in ("y", "mo", "w", "d"):
        if unit in interval:
            msg = f"invalid interval unit for time_range: found {unit!r}"
            raise ValueError(msg)

    if start is None:
        start = time(0, 0, 0)
    if end is None:
        end = time(23, 59, 59, 999999)

    start_pyexpr = parse_into_expression(start)
    end_pyexpr = parse_into_expression(end)

    result = wrap_expr(plr.time_range(start_pyexpr, end_pyexpr, interval, closed))

    if eager:
        return F.select(result).to_series()

    return result


@overload

View on GitHub (pinned to df599052da)

Solutions

  1. Use sub-day units, e.g. interval='24h' or '1h'/'30m'/'15s'/'500ms'
  2. If you actually need dates or datetimes, use pl.date_range or pl.datetime_range instead of time_range
  3. Centralize interval strings per domain so date-scale intervals never reach time_range

Example fix

// before
pl.time_range(time(0, 0), time(23, 59), interval='1d', eager=True)
// after
pl.time_range(time(0, 0), time(23, 59), interval='12h', eager=True)
# or, if day steps were intended:
pl.datetime_range(datetime(2024,1,1), datetime(2024,1,7), interval='1d', eager=True)
Defensive patterns

Strategy: validation

Validate before calling

INVALID_TIME_UNITS = ('y', 'mo', 'w', 'd')
if any(u in interval for u in INVALID_TIME_UNITS):
    raise ValueError(f'time_range interval {interval!r} uses a date-scale unit')

Type guard

def is_subday_interval(interval: str) -> bool:
    return not any(u in interval for u in ('y', 'mo', 'w', 'd'))

Try / catch

try:
    s = pl.time_range(start, end, interval=interval, eager=True)
except ValueError:
    s = pl.datetime_range(..., interval=interval).dt.time

Prevention

When it happens

Trigger: pl.time_range(interval='1d'); pl.time_range('00:00', '23:00', interval='1w'); copying an interval like '1mo' from date_range code; any of 'y', 'mo', 'w', 'd' appearing in the parsed interval string.

Common situations: Reusing date_range/datetime_range intervals for time-of-day grids (e.g. building a daily schedule with '1d' instead of '24h'); migrating from pandas date_range(freq='D') on times; configuration files sharing one interval across date and time ranges.

Related errors


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