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
- Leave exactly one of the four as None — typically the one you want inferred.
- If freq is known, omit either periods or end.
- 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
- Omit exactly one of start/end/periods/freq.
- Validate input arity in wrappers around timedelta_range.
- Avoid passing defaults for all four parameters.
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
- Must provide freq argument if no data is supplied
- 'unit' must be one of 's', 'ms', 'us', 'ns'
- at least 'start' or 'end' should be specified if a 'period'…
- by_row= not allowed
- Cannot add or subtract timedelta64[ns] dtype from
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)