pandas-dev/pandas · error · NotImplementedError

ambiguous is not supported.

Error message

ambiguous is not supported.

What it means

Raised by ArrowExtensionArray._round_temporally (the shared engine behind `.dt.ceil/.dt.floor/.dt.round`) when the `ambiguous` argument is anything other than the default 'raise'. PyArrow's `ceil_temporal/floor_temporal/round_temporal` have no notion of DST-ambiguous-time resolution, so pandas cannot honor 'infer', bool arrays, or 'NaT' for these rounding operations.

Solutions

  1. Omit `ambiguous` (leave it 'raise') — the operation will itself raise if it genuinely hits an ambiguous time, which is the safe default.
  2. If you must disambiguate, tz_localize the result yourself or drop to object/tz-aware datetime64[ns] handling where ambiguous is honored.

Example fix

# before
ser.dt.floor('h', ambiguous='infer')
# after
ser.dt.floor('h')
Defensive patterns

Strategy: validation

Validate before calling

if ambiguous != 'raise':
    raise ValueError("ambiguous is unsupported on arrow rounding; leave default")
ser.dt.floor('h')

Type guard

def arrow_round_accepts_ambiguous(ambiguous) -> bool:
    return ambiguous == 'raise'

Try / catch

try:
    out = ser.dt.floor(freq, ambiguous=ambiguous)
except NotImplementedError as e:
    if "ambiguous is not supported" in str(e):
        out = ser.dt.floor(freq)   # fall back to default 'raise'
    else:
        raise

Prevention

When it happens

Trigger: Calling `ser.dt.floor('h', ambiguous='infer')` (or any non-'raise' ambiguous value) on a tz-aware timestamp[pyarrow] Series that crosses a DST boundary where rounding could land in an ambiguous time.

Common situations: Copying tz_localize kwargs (`ambiguous=...`) into a rounding call; assuming the rounding API mirrors localization's argument surface.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/550852324616a22a. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/arrow/array.py:4200

        return self.dtype.pyarrow_dtype.unit

    def _dt_normalize(self) -> Self:
        result = pc.floor_temporal(self._pa_array, 1, "day")
        return self._from_pyarrow_array(result)

    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",

View on GitHub (pinned to 3b7651241d)