pandas-dev/pandas · error · NotImplementedError

{ambiguous=} is not supported

Error message

{ambiguous=} is not supported

What it means

Raised by ArrowExtensionArray._dt_tz_localize when `ambiguous != "raise"`. The pyarrow assume_timezone call underneath is invoked with ambiguous='raise' only; the ArrowExtensionArray path does not support 'infer', boolean arrays, or 'NaT' for the ambiguous parameter when localizing. Any non-'raise' value triggers NotImplementedError.

Source

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

        if pa.types.is_date(self.dtype.pyarrow_dtype):
            raise ValueError(
                f"to_pydatetime cannot be called with {self.dtype.pyarrow_dtype} type. "
                "Convert to pyarrow timestamp type."
            )
        data = self._pa_array.to_pylist()
        if self._dtype.pyarrow_dtype.unit == "ns":
            data = [None if ts is None else ts.to_pydatetime(warn=False) for ts in data]
        return Series(data, dtype=object)

    def _dt_tz_localize(
        self,
        tz,
        ambiguous: TimeAmbiguous = "raise",
        nonexistent: TimeNonexistent = "raise",
    ) -> Self:
        if ambiguous != "raise":
            raise NotImplementedError(f"{ambiguous=} is not supported")
        nonexistent_pa = {
            "raise": "raise",
            "shift_backward": "earliest",
            "shift_forward": "latest",
        }.get(
            nonexistent,  # type: ignore[arg-type]
            None,
        )
        if nonexistent_pa is None:
            raise NotImplementedError(f"{nonexistent=} is not supported")
        if tz is None:
            result = pc.local_timestamp(self._pa_array)
        else:
            result = pc.assume_timezone(
                self._pa_array, str(tz), ambiguous=ambiguous, nonexistent=nonexistent_pa
            )
        return self._from_pyarrow_array(result)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Pre-disambiguate the fold before localizing, then localize with ambiguous='raise' on a clean subset.
  2. Cast to datetime64[ns] for localization: `s.astype("datetime64[ns]").dt.tz_localize("US/Eastern", ambiguous="infer")`.
  3. Localize to UTC (no DST) if wall-clock semantics are not critical, then tz_convert.
  4. Provide explicit per-row ambiguous flags via the numpy-backed path.

Example fix

# before
s.dt.tz_localize("US/Eastern", ambiguous="infer")  # NotImplementedError

# after
out = s.astype("datetime64[ns]").dt.tz_localize("US/Eastern", ambiguous="infer")
Defensive patterns

Strategy: validation

Validate before calling

def safe_tz_localize(s, tz, nonexistent="raise"):
    if ambiguous != "raise":
        # pyarrow backend cannot resolve fold; use numpy backend
        return s.astype("datetime64[ns]").dt.tz_localize(tz, ambiguous=ambiguous, nonexistent=nonexistent)
    return s.dt.tz_localize(tz, nonexistent=nonexistent)

Type guard

def needs_numpy_localize(ambiguous) -> bool:
    return ambiguous != "raise"

Try / catch

try:
    out = s.dt.tz_localize(tz, ambiguous=ambiguous)
except NotImplementedError:
    out = s.astype("datetime64[ns]").dt.tz_localize(tz, ambiguous=ambiguous)

Prevention

When it happens

Trigger: Calling `s.dt.tz_localize("US/Eastern", ambiguous="infer")` or `ambiguous=[True,False,...]` on a tz-naive pyarrow timestamp Series whose wall-clock times fall in a DST fold. Reached via dt.tz_localize on timestamp[pyarrow].

Common situations: Localizing logs/telemetry timestamped in local wall-clock time crossing a fall-back DST boundary; porting localize code from datetime64[ns] that accepted infer/array ambiguous.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/ab4fb84c41d89462. Report an issue: GitHub.