pandas-dev/pandas · error · ValueError
Could not infer freq from start/end
Error message
Could not infer freq from start/end
What it means
Defensive branch in _get_ordinal_range (marked pragma: no cover) that fires when freq is None and neither start nor end ended up as a Period object, so there is no frequency to inherit. In normal flow at least one bound becomes a Period via Period(start, freq); reaching this line means the inputs defeated that construction path. It is essentially an internal-invariant failure rather than an expected user error.
Source
Thrown at pandas/core/arrays/period.py:1544
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")
if start is NaT or end is NaT:
raise ValueError("start and end must not be NaT")
if freq is None:
if is_start_per:
freq = start.freq
elif is_end_per:
freq = end.freq
else: # pragma: no cover
raise ValueError("Could not infer freq from start/end")
mult = freq.n
if periods is not None:
periods = periods * mult
if start is None:
data = np.arange(
end.ordinal - periods + mult, end.ordinal + 1, mult, dtype=np.int64
)
else:
data = np.arange(
start.ordinal, start.ordinal + periods, mult, dtype=np.int64
)
else:
data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64)
return data, freq
View on GitHub (pinned to 71959b8cb9)
Solutions
- Always pass an explicit freq= to period_range / _get_ordinal_range so freq inference is not required.
- If calling internals directly, ensure at least one bound is a real Period before invoking.
- Report as a pandas bug if hit through the public API, since the branch is marked no-cover.
Example fix
// before pd.core.arrays.period._get_ordinal_range(start, end, periods, freq=None) // after pd.core.arrays.period._get_ordinal_range(start, end, periods, freq='D')
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
from pandas import Period
def safe_get_ordinal_range(start, end, periods, freq):
if freq is None and not isinstance(start, Period) and not isinstance(end, Period):
raise ValueError('Pass an explicit freq; could not infer from start/end')
return pd.core.arrays.period._get_ordinal_range(start, end, periods, freq) Type guard
def has_period_endpoint(start, end) -> bool:
return isinstance(start, pd.Period) or isinstance(end, pd.Period) Try / catch
try:
data, freq = _get_ordinal_range(start, end, periods, freq)
except ValueError as e:
if 'Could not infer freq' in str(e):
freq = 'D'
data, freq = _get_ordinal_range(start, end, periods, freq)
else:
raise Prevention
- Never call _get_ordinal_range without an explicit freq.
- Treat this branch as a bug indicator if reached via public API.
- Ensure at least one bound is a Period when freq is None.
When it happens
Trigger: Reaching this requires freq=None plus both start and end being non-Period after construction (e.g. subclassing/monkeypatching Period, or a future refactor). Practically unreachable through the public period_range API for well-formed inputs.
Common situations: Custom subclasses overriding Period behavior; using private _get_ordinal_range directly with exotic objects; version regressions where the Period coercion path changes.
Related errors
- start and end must have same freq
- start and end must not be NaT
- Quarter must be 1 <= q <= 4
- cannot convert float NaN to integer
- Mismatched Period array lengths
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/537d6df941da430f.
Report an issue: GitHub.