pandas-dev/pandas · error · ValueError
empty separator
Error message
empty separator
What it means
Raised by the pyarrow-backed string mixin's `_str_partition_expand` when the `sep` argument is empty/falsy. pandas intentionally re-raises pyarrow's 'Empty separator' using the wording Python's built-in `str.partition` uses ('empty separator') so every string dtype (object, StringDtype, ArrowDtype[str]) raises identically. It is a `ValueError`. The guard runs before any pyarrow compute call, so no partial work is done.
Source
Thrown at pandas/core/arrays/_arrow_string_mixins.py:510
result = result.cast(pa.int64())
return self._convert_int_result(result)
def _str_partition_expand(self, sep: str) -> pa.ChunkedArray:
"""
Split each string on the first occurrence of ``sep``.
Returns a ``list<string>`` array holding one three-element list per row
-- the part before the separator, the separator, and the part after --
which ``StringMethods._wrap_result`` expands into three columns. Rows
without ``sep`` get two empty strings, matching ``str.partition``.
The caller wraps this in an :class:`ArrowExtensionArray`; the rows are
lists, so it is not of the calling array's own type.
"""
if not sep:
# pyarrow reports this as "Empty separator"; keep str.partition's
# wording so every dtype raises the same way
raise ValueError("empty separator")
str_type = self._pa_array.type
chunks = [
self._partition_chunk(chunk, sep, str_type)
for chunk in self._pa_array.chunks
]
return pa.chunked_array(chunks, type=pa.list_(str_type))
@staticmethod
def _partition_chunk(chunk: pa.Array, sep: str, str_type: pa.DataType) -> pa.Array:
"""
Build the ``list<string>`` rows for one chunk of :meth:`_str_partition_expand`.
Working a chunk at a time keeps the concatenation below within the
offset width of ``str_type``, which matters for columns near the 2 GiB
limit of 32-bit ``string``.
"""
# max_splits=1 gives [before] when sep is absent, else [before, after];View on GitHub (pinned to 3b7651241d)
Solutions
- Pass a non-empty separator string to `Series.str.partition` / `Series.str.rpartition`.
- If the separator comes from user input or config, validate `if not sep: raise ValueError(...)` before calling and surface a clearer message.
- Handle the empty-separator case explicitly in your code (e.g. return the original string in column 0 and empty strings in columns 1-2) rather than relying on the library.
Example fix
// before
s.str.partition(sep=user_sep) # user_sep == '' -> ValueError
// after
if not user_sep:
raise ValueError('separator must be non-empty')
s.str.partition(sep=user_sep) Defensive patterns
Strategy: validation
Validate before calling
if not sep:
raise ValueError('separator must be a non-empty string')
s.str.partition(sep=sep) Type guard
def is_nonempty_str(s: object) -> bool:
return isinstance(s, str) and len(s) > 0 Try / catch
try:
parts = s.str.partition(sep)
except ValueError as e:
if 'empty separator' in str(e):
raise ValueError('Provide a non-empty separator') from e
raise Prevention
- Validate user-supplied separators before passing to .str.partition
- Prefer None as 'unset' sentinel and translate to a real separator
When it happens
Trigger: Calling `Series.str.partition('')` or `Series.str.rpartition('')` on a Series whose dtype is `string[pyarrow]` (ArrowExtensionArray of strings). Also reachable via `.str.partition(sep='')` where `sep` resolves to an empty string at runtime, e.g. `sep=some_var or ''`.
Common situations: Passing a user-supplied separator that was not validated; using a default of `''` instead of `None`; migrating from object dtype to `string[pyarrow]` and discovering the empty-sep path now goes through this mixin.
Related errors
- __invert__ is not supported for string dtypes
- operation '{op.__name__}' not supported for dtype '{self.dty
- Can only string multiply by an integer.
- Lengths of operands do not match: {len(self)} != {len(other)
- Must specify a valid frequency: {freq}
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/416de25fbc509293.
Report an issue: GitHub.