pandas-dev/pandas · error · ValueError
Of the four parameters: start, end, periods, and freq, exact
Error message
Of the four parameters: start, end, periods, and freq, exactly three must be specified
What it means
Raised by TimedeltaArray._generate_range when com.count_not_none(start, end, periods, freq) != 3. The range-generation contract is 'exactly three of the four must be specified' so the fourth is inferred; specifying fewer (under-determined) or all four (over-determined, contradictory) is ambiguous and rejected. This mirrors date_range's contract.
Source
Thrown at pandas/core/arrays/timedeltas.py:288
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 71959b8cb9)
Solutions
- Provide exactly three of start, end, periods, freq; drop or add one so the count is 3.
- If you want inferrable behavior, leave freq=None and pass start+end+periods.
- Audit call sites: ensure defaults do not collide (e.g. periods defaulting to a non-None value).
Example fix
# before pd.timedelta_range(start='1 day', end='5 days', periods=5, freq='1D') # 4 args # after pd.timedelta_range(start='1 day', end='5 days', periods=5)
Defensive patterns
Strategy: validation
Validate before calling
def exactly_three_of_four(start, end, periods, freq):
count = sum(x is not None for x in (start, end, periods, freq))
if count != 3:
raise ValueError(f'Expected exactly 3 of 4, got {count}')
return True Type guard
def is_three_of_four(start, end, periods, freq) -> bool:
return sum(x is not None for x in (start, end, periods, freq)) == 3 Try / catch
try:
return pd.timedelta_range(start, end, periods, freq)
except ValueError as e:
if 'exactly three must be specified' in str(e):
return pd.timedelta_range(start=start, end=end, periods=periods)
raise Prevention
- Make exactly one of the four args None in wrapper defaults.
- Add a unit test matrix covering 2/3/4-arg combinations.
- Avoid passing both periods and freq unless intentional.
When it happens
Trigger: Calling timedelta_range with only two of {start,end,periods,freq}, or with all four provided. Also when a caller supplies start+end+freq+periods simultaneously.
Common situations: Parameterized builders that conditionally set some args to None; copy-paste leaving an extra argument; refactoring from date_range without dropping the now-redundant arg.
Related errors
- Must provide freq argument if no data is supplied
- check_like must be False if check_index is False
- Values resolution does not match dtype.
- 'unit' must be one of 's', 'ms', 'us', 'ns'
- 'value' should be a Timedelta.
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/ab3a28ca8297bb33.
Report an issue: GitHub.