pandas-dev/pandas · error · ValueError

Must provide freq argument if no data is supplied

Error message

Must provide freq argument if no data is supplied

What it means

Raised by TimedeltaArray._generate_range when freq is None and at least one of start/end/periods is also None. Generating a timedelta range requires either a frequency to step by, or enough anchor data to infer one; without freq and without full anchor data the sequence is under-specified. This is the first of two validation checks in range generation.

Source

Thrown at pandas/core/arrays/timedeltas.py:285

                # numeric data is interpreted in the dtype's unit, matching
                #  to_timedelta(data, unit=...); mixed Timedelta/numeric data
                #  keeps the "ns" default, unlike to_timedelta
                unit = np.datetime_data(dtype)[0]

        data = sequence_to_td64ns(data, copy=copy, unit=unit)

        if dtype is not None:
            data = astype_overflowsafe(data, dtype=dtype, copy=False)

        return cls._simple_new(data, dtype=data.dtype)

    @classmethod
    def _generate_range(
        cls, start, end, periods, freq, closed=None, *, unit: TimeUnit
    ) -> Self:
        periods = dtl.validate_periods(periods)
        if freq is None and any(x is None for x in [periods, start, end]):
            raise ValueError("Must provide freq argument if no data is supplied")

        if com.count_not_none(start, end, periods, freq) != 3:
            raise ValueError(
                "Of the four parameters: start, end, periods, "
                "and freq, exactly three must be specified"
            )

        if start is not None:
            start = Timedelta(start).as_unit("ns")

        if end is not None:
            end = Timedelta(end).as_unit("ns")

        if unit not in ["s", "ms", "us", "ns"]:
            raise ValueError("'unit' must be one of 's', 'ms', 'us', 'ns'")

        if start is not None and unit is not None:
            start = start.as_unit(unit, round_ok=False)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Provide a freq argument, e.g. timedelta_range(start='1 day', freq='1D', periods=5).
  2. Supply all three of start, end, and periods (freq=None is then inferable).
  3. Validate your config dict before calling: ensure freq is set whenever start or end or periods is absent.

Example fix

# before
pd.timedelta_range(start='1 day')  # ValueError
# after
pd.timedelta_range(start='1 day', freq='1D', periods=5)
Defensive patterns

Strategy: validation

Validate before calling

def validate_range_args(start, end, periods, freq):
    if freq is None and any(x is None for x in (start, end, periods)):
        raise ValueError('Provide freq when any of start/end/periods is missing')
    return True

Type guard

def has_freq_or_full_anchors(start, end, periods, freq) -> bool:
    return freq is not None or all(x is not None for x in (start, end, periods))

Try / catch

try:
    return pd.timedelta_range(start=start, periods=periods)
except ValueError as e:
    if 'Must provide freq' in str(e):
        return pd.timedelta_range(start=start, periods=periods, freq='1D')
    raise

Prevention

When it happens

Trigger: Calling timedelta_range(start='1 day') with neither end, periods, nor freq; or pd.TimedeltaIndex(... ) construction routing into _generate_range with freq=None and a missing anchor. The check at timedeltas.py:284 is `freq is None and any(x is None for x in [periods, start, end])`.

Common situations: Programmatically building ranges from partial config; forgetting to pass freq when only one bound is given; defaulting arguments to None and not substituting freq.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/a6a9eb25c34cea4f. Report an issue: GitHub.