{"record":{"id":"fd046a65af68c530","repo":"pandas-dev/pandas","slug":"freq-is-not-supported","errorCode":null,"errorMessage":"{freq=} is not supported","messagePattern":"(.+?) is not supported","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":4196,"sourceCode":"        pa_supported_unit = {\n            \"Y\": \"year\",\n            \"YS\": \"year\",\n            \"Q\": \"quarter\",\n            \"QS\": \"quarter\",\n            \"M\": \"month\",\n            \"MS\": \"month\",\n            \"W\": \"week\",\n            \"D\": \"day\",\n            \"h\": \"hour\",\n            \"min\": \"minute\",\n            \"s\": \"second\",\n            \"ms\": \"millisecond\",\n            \"us\": \"microsecond\",\n            \"ns\": \"nanosecond\",\n        }\n        unit = pa_supported_unit.get(offset._prefix, None)\n        if unit is None:\n            raise ValueError(f\"{freq=} is not supported\")\n        multiple = offset.n\n        rounding_method = getattr(pc, f\"{method}_temporal\")\n        result = rounding_method(self._pa_array, multiple=multiple, unit=unit)\n        return self._from_pyarrow_array(result)\n\n    def _dt_ceil(\n        self,\n        freq,\n        ambiguous: TimeAmbiguous = \"raise\",\n        nonexistent: TimeNonexistent = \"raise\",\n    ) -> Self:\n        return self._round_temporally(\"ceil\", freq, ambiguous, nonexistent)\n\n    def _dt_floor(\n        self,\n        freq,\n        ambiguous: TimeAmbiguous = \"raise\",\n        nonexistent: TimeNonexistent = \"raise\",","sourceCodeStart":4178,"sourceCodeEnd":4214,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L4178-L4214","documentation":"Raised by ArrowExtensionArray._round_temporally when the parsed offset's prefix is not in the supported mapping of pandas freq prefixes to pyarrow temporal units. Supported prefixes are Y, YS, Q, QS, M, MS, W, D, h, min, s, ms, us, ns. Business/custom offsets (e.g. 'B', 'SMS', 'CBM', 'BH') and any prefix outside that map hit ValueError. Reached through dt.ceil/floor/round on pyarrow timestamps.","triggerScenarios":"Calling `s.dt.floor(\"B\")` (business day), `s.dt.round(\"W-MON\")` (anchored week), `s.dt.ceil(\"SMS\")` (semi-month start), or any custom/business anchored frequency on a timestamp[pyarrow] Series.","commonSituations":"Financial/business calendars that rely on business-day rounding; reusing anchored freq strings from numpy-backed datetime code.","solutions":["Round to a supported base unit then post-process for business logic, e.g. round to 'D' then snap to nearest business day with a custom offset.","Cast to datetime64[ns] which supports business offsets via numpy path: `s.astype(\"datetime64[ns]\").dt.floor(\"B\")`.","Use only plain unit prefixes: 'D','h','min','s','ms','us','ns' with an integer multiple.","Switch to a non-anchored frequency that maps directly to a pyarrow temporal unit."],"exampleFix":"# before\ns.dt.floor(\"B\")  # ValueError: B is not supported\n\n# after: use numpy backend for business rounding\ns.astype(\"datetime64[ns]\").dt.floor(\"B\")","handlingStrategy":"validation","validationCode":"from pandas.tseries.frequencies import to_offset\n\nSUPPORTED_PREFIXES = {\"Y\",\"YS\",\"Q\",\"QS\",\"M\",\"MS\",\"W\",\"D\",\"h\",\"min\",\"s\",\"ms\",\"us\",\"ns\"}\n\ndef is_supported_freq(freq) -> bool:\n    off = to_offset(freq)\n    return off is not None and off._prefix in SUPPORTED_PREFIXES\n\ndef safe_round(s, freq, method=\"floor\"):\n    if not is_supported_freq(freq):\n        raise ValueError(f\"{freq!r} not supported by pyarrow rounding; use plain units\")\n    return s.dt.__getattribute__(method)(freq)","typeGuard":"from pandas.tseries.frequencies import to_offset\n\ndef is_supported_freq(freq) -> bool:\n    off = to_offset(freq)\n    return off is not None and off._prefix in {\"Y\",\"YS\",\"Q\",\"QS\",\"M\",\"MS\",\"W\",\"D\",\"h\",\"min\",\"s\",\"ms\",\"us\",\"ns\"}","tryCatchPattern":"try:\n    out = s.dt.floor(freq)\nexcept ValueError as e:\n    if \"is not supported\" in str(e):\n        out = s.astype(\"datetime64[ns]\").dt.floor(freq)\n    else:\n        raise","preventionTips":["Avoid business/custom anchored frequencies for pyarrow timestamp rounding.","Cast to datetime64[ns] when business offsets are required.","Whitelist pyarrow-supported freq prefixes in shared utilities."],"tags":["pyarrow","datetime-accessor","frequency","validation"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}