pandas-dev/pandas · error · TypeError
expected a string object, not {type(pat).__name__}
Error message
expected a string object, not {type(pat).__name__} What it means
Raised by ArrowExtensionArray._str_rsplit when `pat` is not None and is not a Python str (e.g. bytes, an int, or a numpy scalar). The PyArrow split functions require a string pattern, so any non-str separator is rejected with TypeError before being forwarded to pc.split_pattern. Reached via Series.str.rsplit on a pyarrow-string Series.
Source
Thrown at pandas/core/arrays/arrow/array.py:3749
if n in {-1, 0}:
n = None
if pat is None:
split_func = pc.utf8_split_whitespace
elif regex is True:
split_func = functools.partial(pc.split_pattern_regex, pattern=pat)
elif regex is False:
split_func = functools.partial(pc.split_pattern, pattern=pat)
# GH#58321: regex is None — infer: single-char literal, multi-char regex
elif len(pat) == 1:
split_func = functools.partial(pc.split_pattern, pattern=pat)
else:
split_func = functools.partial(pc.split_pattern_regex, pattern=pat)
return self._from_pyarrow_array(split_func(self._pa_array, max_splits=n))
def _str_rsplit(self, pat: str | None = None, n: int | None = -1) -> Self:
if pat is not None and not isinstance(pat, str):
msg = f"expected a string object, not {type(pat).__name__}"
raise TypeError(msg)
if n in {-1, 0}:
n = None
if pat is None:
return self._from_pyarrow_array(
pc.utf8_split_whitespace(self._pa_array, max_splits=n, reverse=True)
)
return self._from_pyarrow_array(
pc.split_pattern(self._pa_array, pat, max_splits=n, reverse=True)
)
def _str_translate(self, table: dict[int, str]) -> Self:
predicate = lambda val: val.translate(table)
result = self._apply_elementwise(predicate)
return self._from_pyarrow_array(pa.chunked_array(result))
def _str_wrap(self, width: int, **kwargs) -> Self:
kwargs["width"] = width
tw = textwrap.TextWrapper(**kwargs)View on GitHub (pinned to 71959b8cb9)
Solutions
- Pass a str separator: `s.str.rsplit(",", n=1)`.
- Decode bytes first: `sep.decode() if isinstance(sep, bytes) else sep`.
- Coerce loaded config values: `str(sep)` before calling rsplit.
- Double-check argument order: signature is `.str.rsplit(pat=None, n=-1)`.
Example fix
# before
s = pd.Series(["a,b,c"], dtype="string[pyarrow]")
s.str.rsplit(b",") # TypeError: expected a string object, not bytes
# after
s.str.rsplit(",") Defensive patterns
Strategy: type-guard
Validate before calling
def safe_rsplit(s, pat=None, n=-1):
if pat is not None and not isinstance(pat, str):
raise TypeError(f"pat must be str or None, got {type(pat).__name__}")
return s.str.rsplit(pat, n=n) Type guard
def is_str_or_none(v) -> bool:
return v is None or isinstance(v, str) Try / catch
try:
out = s.str.rsplit(pat, n=n)
except TypeError as e:
if "expected a string object" in str(e):
out = s.str.rsplit(str(pat) if pat is not None else None, n=n)
else:
raise Prevention
- Normalize separators to str at config-load time.
- Add type annotations to helper functions that wrap str.rsplit.
- Beware bytes separators from binary protocols; decode before splitting.
When it happens
Trigger: Calling `s.str.rsplit(separator)` where `separator` is bytes (`b","`), a numpy str_, an int, or None mishandled. Mixing up positional args so a non-str value lands in the `pat` slot also triggers it.
Common situations: Data pipelines that split on bytes read from binary protocols; config-driven separators loaded from JSON/YAML that come back as non-str; passing `n` into the `pat` position by mistake.
Related errors
- '{type(self).__name__}' object is not iterable
- __invert__ is not supported for string dtypes
- unary '-' not supported for dtype '{self.dtype}'
- operation '{op.__name__}' not supported for dtype '{self.dty
- Can only string multiply by an integer.
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/d71f4e8cd2dabb0d.
Report an issue: GitHub.