pandas-dev/pandas · error · ValueError

Of the four parameters: start, end, periods, and freq…

Error message

Of the four parameters: start, end, periods, and freq, exactly three must be specified

What it means

TimedeltaArray._generate_range enforces that exactly three of (start, end, periods, freq) are specified. Passing all four, only two, or any other count raises ValueError because the fourth parameter must be left for pandas to compute.

Solutions

  1. Leave exactly one of the four as None — typically the one you want inferred.
  2. If freq is known, omit either periods or end.
  3. If periods is known, omit either freq or end.

Example fix

// before
pd.timedelta_range('1 day', '5 days', 5, '1D')  # all 4 -> ValueError
// after
pd.timedelta_range('1 day', '5 days', freq='1D')  # periods inferred
Defensive patterns

Strategy: validation

Validate before calling

def validate_td_range_args(start, end, periods, freq):
    import pandas.core.common as com
    if com.count_not_none(start, end, periods, freq) != 3:
        raise ValueError('Exactly three of start, end, periods, freq must be set')

Type guard

def exactly_three_of_four(start, end, periods, freq) -> bool:
    import pandas.core.common as com
    return com.count_not_none(start, end, periods, freq) == 3

Try / catch

try:
    pd.timedelta_range(start, end, periods, freq)
except ValueError as e:
    if 'exactly three must be specified' in str(e):
        # leave one of the four as None and retry
        pd.timedelta_range(start=start, end=end, freq=freq)
    else:
        raise

Prevention

When it happens

Trigger: pd.timedelta_range(start, end, periods, freq) all set; pd.timedelta_range(start, end) with only two; pd.timedelta_range(start, periods, freq, end) (over-specified).

Common situations: Wrapping timedelta_range in a function that fills every parameter from defaults; passing a freq along with all of start/end/periods because the caller was unsure which to omit.

Related errors


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

Appendix: source

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

                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)
        if end is not None and unit is not None:
            end = end.as_unit(unit, round_ok=False)

View on GitHub (pinned to 3b7651241d)