pandas-dev/pandas · error · NotImplementedError

Only flags=0 is implemented.

Error message

Only flags=0 is implemented.

What it means

Raised by ArrowExtensionArray._str_extract when the regex `flags` argument is non-zero. The PyArrow-backed string `str.extract` delegates to pyarrow.compute.extract_regex, which has no parameter for re-style flags (IGNORECASE, MULTILINE, etc.), so pandas can only honor flags=0. Passing any flag value short-circuits before compilation.

Solutions

  1. Drop the flags argument (use flags=0, the default) and instead embed the flag semantics directly in the pattern, e.g. use `(?i)...` for IGNORECASE, `(?m)...` for MULTILINE.
  2. If inline flags are insufficient, cast the Series to object dtype first (`ser.astype(object)`) so the numpy/object str.extract path handles the flags.

Example fix

# before
ser.str.extract(r"(?P<word>[a-z]+)", flags=re.IGNORECASE)
# after
ser.str.extract(r"(?i)(?P<word>[a-z]+)")
Defensive patterns

Strategy: validation

Validate before calling

import re
# Validate that flags is zero before calling .str.extract on arrow strings
if flags := getattr(my_flags, "value", my_flags):
    raise ValueError(f"flags={flags} unsupported on string[pyarrow]; inline the flag in pat instead")
ser.str.extract(pat, flags=0)

Type guard

def supports_extract_flags(ser) -> bool:
    # arrow path does not support flags; object path does
    return ser.dtype == object

Try / catch

try:
    out = ser.str.extract(pat, flags=flags)
except NotImplementedError as e:
    if "flags=0" in str(e):
        out = ser.astype(object).str.extract(pat, flags=flags)
    else:
        raise

Prevention

When it happens

Trigger: Calling `ser.str.extract(pat, flags=re.IGNORECASE)` (or any non-zero flag) on a Series backed by a pyarrow dtype (e.g. ArrowExtensionArray of string[pyarrow]). Also triggered via `.extractall` routes that funnel into `_str_extract`.

Common situations: Copying working regex code from a numpy/object-string Series onto a pyarrow-backed Series; enabling pyarrow string dtype as the default and forgetting that the arrow path is more restrictive than the object path.

Related errors


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

Appendix: source

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

    def _str_rpartition(self, sep: str, expand: bool) -> Self:
        predicate = lambda val: val.rpartition(sep)
        result = self._apply_elementwise(predicate)
        return self._from_pyarrow_array(pa.chunked_array(result))

    def _str_casefold(self) -> Self:
        predicate = lambda val: val.casefold()
        result = self._apply_elementwise(predicate)
        return self._from_pyarrow_array(pa.chunked_array(result))

    def _str_encode(self, encoding: str, errors: str = "strict") -> Self:
        predicate = lambda val: val.encode(encoding, errors)
        result = self._apply_elementwise(predicate)
        return self._from_pyarrow_array(pa.chunked_array(result))

    def _str_extract(self, pat: str, flags: int = 0, expand: bool = True):
        if flags:
            raise NotImplementedError("Only flags=0 is implemented.")
        groups = re.compile(pat).groupindex.keys()
        if len(groups) == 0:
            raise ValueError(f"{pat=} must contain a symbolic group name.")
        result = pc.extract_regex(self._pa_array, pat)
        if expand:
            return {
                col: self._from_pyarrow_array(pc.struct_field(result, [i]))
                for col, i in zip(groups, range(result.type.num_fields), strict=True)
            }
        else:
            return type(self)(pc.struct_field(result, [0]))

    def _str_findall(self, pat: str, flags: int = 0) -> Self:
        regex = re.compile(pat, flags=flags)
        predicate = lambda val: regex.findall(val)
        result = self._apply_elementwise(predicate)
        return self._from_pyarrow_array(pa.chunked_array(result))

View on GitHub (pinned to 3b7651241d)