pandas-dev/pandas · error · NotImplementedError

nonexistent is not supported.

Error message

nonexistent is not supported.

What it means

Raised by ArrowExtensionArray._round_temporally when the `nonexistent` argument is anything other than the default 'raise'. Temporal rounding delegates to pyarrow's round_temporal family, which has no parameter to resolve nonexistent (skipped-by-DST-forward) times, so 'shift_forward'/'shift_backward'/'NaT' cannot be honored during rounding.

Solutions

  1. Drop the `nonexistent` argument from the rounding call (use the default 'raise').
  2. Handle non-existent times separately via tz_localize, which does support these strategies on the arrow path.

Example fix

# before
ser.dt.ceil('h', nonexistent='shift_forward')
# after
ser.dt.ceil('h')
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

def arrow_round_accepts_nonexistent(nonexistent) -> bool:
    return nonexistent == 'raise'

Try / catch

try:
    out = ser.dt.ceil(freq, nonexistent=nonexistent)
except NotImplementedError as e:
    if "nonexistent is not supported" in str(e):
        out = ser.dt.ceil(freq)
    else:
        raise

Prevention

When it happens

Trigger: Calling `ser.dt.ceil('h', nonexistent='shift_forward')` (or any non-'raise' nonexistent value) on a timestamp[pyarrow] Series; the guard fires immediately regardless of whether the data actually contains a skipped time.

Common situations: Mirroring the nonexistent handling accepted by tz_localize into a ceil/floor/round call; spring-forward-DST data.

Related errors


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

Appendix: source

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

    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",
            "us": "microsecond",
            "ns": "nanosecond",

View on GitHub (pinned to 3b7651241d)