pandas-dev/pandas · error · ValueError
Must specify a valid frequency: {freq}
Error message
Must specify a valid frequency: {freq} What it means
Raised by ArrowExtensionArray._round_temporally when pandas.tseries.frequencies.to_offset(freq) returns None, i.e. the `freq` string cannot be parsed as a valid pandas offset alias. The pyarrow rounding path requires a recognized frequency to map to a pyarrow temporal unit. Reached through dt.ceil/floor/round on a pyarrow-backed timestamp Series.
Source
Thrown at pandas/core/arrays/arrow/array.py:4177
def _dt_strftime(self, format: str) -> Self:
result = pc.strftime(self._pa_array, format=format)
return self._from_pyarrow_array(result)
def _round_temporally(
self,
method: Literal["ceil", "floor", "round"],
freq,
ambiguous: TimeAmbiguous = "raise",
nonexistent: TimeNonexistent = "raise",
) -> Self:
if ambiguous != "raise":
raise NotImplementedError("ambiguous is not supported.")
if nonexistent != "raise":
raise NotImplementedError("nonexistent is not supported.")
offset = to_offset(freq)
if offset is None:
raise ValueError(f"Must specify a valid frequency: {freq}")
pa_supported_unit = {
"Y": "year",
"YS": "year",
"Q": "quarter",
"QS": "quarter",
"M": "month",
"MS": "month",
"W": "week",
"D": "day",
"h": "hour",
"min": "minute",
"s": "second",
"ms": "millisecond",
"us": "microsecond",
"ns": "nanosecond",
}
unit = pa_supported_unit.get(offset._prefix, None)
if unit is None:View on GitHub (pinned to 71959b8cb9)
Solutions
- Use a valid alias: 's','min','h','D','W','M','MS','Q','QS','Y','YS','ms','us','ns' optionally prefixed by a multiple like '30min'.
- Validate with `pd.tseries.frequencies.to_offset(freq)` before calling; if it returns None, reject early.
- Pass a DateOffset instance that to_offset understands, e.g. `pd.offsets.Hour()`.
- Check for trailing/leading whitespace or typos in the string.
Example fix
# before
s.dt.floor("30mins") # typo -> ValueError
# after
s.dt.floor("30min") Defensive patterns
Strategy: validation
Validate before calling
from pandas.tseries.frequencies import to_offset
def is_valid_freq(freq) -> bool:
try:
return to_offset(freq) is not None
except (ValueError, TypeError):
return False
def safe_round(s, freq, method="floor"):
if not is_valid_freq(freq):
raise ValueError(f"Invalid frequency: {freq!r}")
return s.dt.__getattribute__(method)(freq) Type guard
from pandas.tseries.frequencies import to_offset
def is_valid_freq(freq) -> bool:
try:
return to_offset(freq) is not None
except Exception:
return False Try / catch
try:
out = s.dt.floor(freq)
except ValueError as e:
if "valid frequency" in str(e):
raise ValueError(f"Fix freq alias: {freq!r}. Valid: s,min,h,D,W,M,MS,Q,QS,Y,YS,ms,us,ns") from e
raise Prevention
- Validate freq with to_offset() before rounding.
- Whitelist supported freq aliases in config-driven code.
- Pass DateOffset instances instead of strings when possible.
When it happens
Trigger: Calling `s.dt.floor("xyz")`, `s.dt.round("")`, `s.dt.ceil(None)` (where None is passed positionally), or any unparseable/non-string freq on timestamp[pyarrow]. Also when freq is a malformed alias like '1X'.
Common situations: Typos in freq strings; dynamically building freq from user input; passing a numeric instead of a string; confusing the freq alias with a DateOffset object that to_offset cannot parse.
Related errors
- {freq=} is not supported
- Invalid side: {side}. Side must be one of 'left', 'right', '
- invalid normalization form
- {pat=} must contain a symbolic group name.
- '{self.dtype}' does not have duration components
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/3193d7aa6d98fdf4.
Report an issue: GitHub.