pandas-dev/pandas · error · ValueError
Of the three parameters: start, end, and periods, exactly tw
Error message
Of the three parameters: start, end, and periods, exactly two must be specified
What it means
Raised by _get_ordinal_range when com.count_not_none(start, end, periods) != 2. A period range is fully determined by exactly two of {start, end, periods} together with freq; supplying all three is over-determined and supplying fewer than two is under-determined, both rejected.
Source
Thrown at pandas/core/arrays/period.py:1516
"Pass `freq` explicitly instead.",
Pandas4Warning,
stacklevel=find_stack_level(),
)
freq = inferred_freq
data = data._values
elif isinstance(data, (ABCIndex, ABCSeries)):
data = data._values
reso = get_unit_from_dtype(data.dtype)
freq = Period._maybe_convert_freq(freq)
base = freq._period_dtype_code
return c_dt64arr_to_periodarr(data.view("i8"), base, tz, reso=reso), freq
def _get_ordinal_range(start, end, periods, freq, mult: int = 1):
if com.count_not_none(start, end, periods) != 2:
raise ValueError(
"Of the three parameters: start, end, and periods, "
"exactly two must be specified"
)
if freq is not None:
freq = to_offset(freq, is_period=True)
mult = freq.n
if start is not None:
start = Period(start, freq)
if end is not None:
end = Period(end, freq)
is_start_per = isinstance(start, Period)
is_end_per = isinstance(end, Period)
if is_start_per and is_end_per and start.freq != end.freq:
raise ValueError("start and end must have same freq")View on GitHub (pinned to 71959b8cb9)
Solutions
- Pass exactly two: start + end, start + periods, or end + periods.
- Drop the redundant parameter if all three are set.
- Compute the missing one upstream and pass exactly two.
Example fix
# before pd.period_range(start='2020-01-01', end='2020-01-05', periods=5, freq='D') # after pd.period_range(start='2020-01-01', end='2020-01-05', freq='D') # or pd.period_range(start='2020-01-01', periods=5, freq='D')
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def exactly_two_of(start, end, periods, freq):
provided = sum(x is not None for x in (start, end, periods))
if provided != 2:
raise ValueError(f'Exactly two of start/end/periods required, got {provided}')
return pd.period_range(start=start, end=end, periods=periods, freq=freq) Type guard
def has_exactly_two_anchors(start, end, periods) -> bool:
return sum(x is not None for x in (start, end, periods)) == 2 Try / catch
try:
rng = pd.period_range(start=start, end=end, periods=periods, freq=freq)
except ValueError:
# drop periods if start and end are both set
rng = pd.period_range(start=start, end=end, freq=freq) Prevention
- Enforce 'exactly two of three' in calling code/config validators.
- Default unset params to None (not 0) so the count is meaningful.
- Unit-test range builders with all combinations of None.
When it happens
Trigger: pd.period_range(start=..., end=..., periods=...) (all three); pd.period_range(freq='D') (none of the three); pd.period_range(start='2020-01-01', freq='D') (only one).
Common situations: Dynamic config where all three fields default to provided values. Refactors that accidentally pass periods alongside start+end. UI forms exposing all three fields.
Related errors
- Not enough parameters to construct Period range
- dtype must be PeriodDtype
- specified freq and dtype are different
- Invalid dtype {dtype} for PeriodArray
- Incorrect dtype
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/35c99bd70bdf9a8b.
Report an issue: GitHub.