pola-rs/polars · error · TypeError
"extract_groups" expects a `str`, given a {qualified_type_na
Error message
"extract_groups" expects a `str`, given a {qualified_type_name(pattern)!r} What it means
Expr.str.extract_groups returns a struct whose field names come from the named capture groups of the pattern, so the regex must be a literal Python str known at plan-build time. Passing an Expr, Series, bytes, or None raises this TypeError before execution. Column-driven patterns belong to the other extractors in the same namespace.
Source
Thrown at py-polars/src/polars/expr/string.py:1750
>>> (
... df.with_columns(
... captures=pl.col("url").str.extract_groups(pattern)
... ).with_columns(name=pl.col("captures").struct["1"].str.to_uppercase())
... )
shape: (3, 3)
┌─────────────────────────────────┬───────────────────────┬──────────┐
│ url ┆ captures ┆ name │
│ --- ┆ --- ┆ --- │
│ str ┆ struct[2] ┆ str │
╞═════════════════════════════════╪═══════════════════════╪══════════╡
│ http://vote.com/ballon_dor?can… ┆ {"messi","python"} ┆ MESSI │
│ http://vote.com/ballon_dor?can… ┆ {"weghorst","polars"} ┆ WEGHORST │
│ http://vote.com/ballon_dor?err… ┆ {null,null} ┆ null │
└─────────────────────────────────┴───────────────────────┴──────────┘
"""
if not isinstance(pattern, str):
msg = f'"extract_groups" expects a `str`, given a {qualified_type_name(pattern)!r}'
raise TypeError(msg)
return wrap_expr(self._pyexpr.str_extract_groups(pattern))
def count_matches(self, pattern: str | Expr, *, literal: bool = False) -> Expr:
r"""
Count all successive non-overlapping regex matches.
.. engine-support:: in-memory, streaming, distributed
Parameters
----------
pattern
A valid regular expression pattern, compatible with the `regex crate
<https://docs.rs/regex/latest/regex/>`_.
literal
Treat `pattern` as a literal string, not as a regular expression.
Returns
-------View on GitHub (pinned to df599052da)
Solutions
- Pass the regex as a plain string with named groups: .str.extract_groups(r'(?P<year>\d{4})-(?P<month>\d{2})')
- If patterns live in a column, use .str.extract_many(pl.col('patterns')) or map_batches with Python re
- Decode bytes patterns to str before calling
Example fix
# before
pl.col('url').str.extract_groups(pl.col('pattern_col'))
# after (literal pattern)
pl.col('url').str.extract_groups(r'(?P<host>[^/]+)/(?P<path>.*)')
# after (per-row patterns)
pl.col('url').str.extract_many(pl.col('pattern_col')) Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(pattern, str):
pattern = str(pattern) # or raise your own error
expr = pl.col('url').str.extract_groups(pattern) Type guard
def is_literal_pattern(x: object) -> bool:
return isinstance(x, str) Prevention
- Keep regex patterns as module-level str constants
- Use extract_many for per-row patterns from a column
- Decode bytes patterns at ingestion time
- Type-annotate pattern parameters as str so checkers catch misuse
When it happens
Trigger: .str.extract_groups(pl.col('pattern')) or passing a Series of patterns; pattern stored as bytes; pattern=None from optional config; mixing this method up with extract/extract_many which do accept pattern columns.
Common situations: Patterns loaded from a config table or another column; serialized bytes patterns; refactoring code between extract_groups (literal regex, struct output) and extract_many (per-row pattern lists).
Related errors
- "pad_start" expects a `str`, given a {qualified_type_name(fi
- "pad_end" expects a `str`, given a {qualified_type_name(fill
- `replace_with` argument is required if `patterns` argument i
- expected type 'int | str', got {qualified_type_name(item)!r}
- mapping item must be a datatype or datatype expression; foun
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/b863b73a6b188fae.
Report an issue: GitHub.