pola-rs/polars · error · TypeError

'prefix' must be a string; found

Error message

'prefix' must be a string; found {qualified_type_name(prefix)!r}

What it means

Type guard in Expr.cat.starts_with: the prefix argument must be a plain str; passing an Expr, Series, bytes, or other non-string type raises TypeError after inspecting the value's qualified type name.

Solutions

  1. Convert the argument with str(prefix) before the call
  2. Decode bytes: prefix.decode('utf-8')
  3. Validate isinstance(prefix, str) before calling
  4. Check that the right variable is passed (prefix vs its length or id)

Example fix

// before
cat_col.cat.starts_with(b'app')
// after
cat_col.cat.starts_with('app')
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(prefix, str):
    raise TypeError(f'prefix must be str, got {type(prefix).__name__}')

Type guard

def is_str(x) -> bool:
    return isinstance(x, str)

Try / catch

try:
    e = col.cat.starts_with(prefix)
except TypeError as e:
    if 'must be a string' in str(e):
        e = col.cat.starts_with(prefix.decode() if isinstance(prefix, bytes) else str(prefix))
    else:
        raise

Prevention

When it happens

Trigger: Calling pl.col('c').cat.starts_with(123), starts_with(b'app'), starts_with(None), or passing a variable holding an int/bytes instead of a string.

Common situations: Passing numeric prefixes read from config; passing bytes from network/file input without decoding; forgetting f-string/str() conversion when building the prefix dynamically.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/eeadce44158ec8a0. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/expr/categorical.py:176

        │ mango  ┆ false      │
        │ null   ┆ null       │
        └────────┴────────────┘

        Using `starts_with` as a filter condition:

        >>> df.filter(pl.col("fruits").cat.starts_with("app"))
        shape: (1, 1)
        ┌────────┐
        │ fruits │
        │ ---    │
        │ cat    │
        ╞════════╡
        │ apple  │
        └────────┘
        """
        if not isinstance(prefix, str):
            msg = f"'prefix' must be a string; found {qualified_type_name(prefix)!r}"
            raise TypeError(msg)
        return wrap_expr(self._pyexpr.cat_starts_with(prefix))

    def ends_with(self, suffix: str) -> Expr:
        """
        Check if string representations of values end with a substring.

        .. engine-support:: in-memory, streaming, distributed

        Parameters
        ----------
        suffix
            Suffix substring.

        See Also
        --------
        contains : Check if string reprs contains a substring that matches a pattern.
        starts_with : Check if string reprs start with a substring.

View on GitHub (pinned to fe841f959e)