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

TimedeltaArray._generate_range requires a freq when constructing a range without complete data. If freq is None and any of periods/start/end is None, pandas cannot synthesize a regular sequence and refuses rather than guess.

Solutions

  1. Provide a freq string or DateOffset/Timedelta: pd.timedelta_range(start, periods, freq='1D').
  2. Provide all three of start/end/periods (freq omitted) so the fourth is inferred.
  3. Validate inputs up front and default freq when missing.

Example fix

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

Strategy: validation

Validate before calling

def build_td_range(start=None, end=None, periods=None, freq=None):
    if freq is None and any(v is None for v in [periods, start, end]):
        raise ValueError('freq required when any of start/end/periods is missing')
    return pd.timedelta_range(start=start, end=end, periods=periods, freq=freq)

Type guard

def td_range_inputs_valid(start, end, periods, freq) -> bool:
    return freq is not None or all(v is not None for v in [start, end, periods])

Try / catch

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

Prevention

When it happens

Trigger: pd.timedelta_range(start='1 day', periods=None, freq=None); calling _generate_range(start=None, end=None, periods=5, freq=None); building a range with only two of the four coordinates when freq is absent.

Common situations: Dynamically building a range from user input where freq was optional; omitting freq expecting it to be inferred (timedelta does not infer freq).

Related errors


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

Appendix: source

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

                # 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 3b7651241d)