pola-rs/polars · error

expected `by_predicate` to be an expression, got {qualified_

Error message

expected `by_predicate` to be an expression, got {qualified_type_name(by_predicate)!r}

What it means

DataFrame.row's `by_predicate` parameter only accepts a pl.Expr — the whole boolean predicate, not a column name, list of names, or Series. Unlike selection APIs where strings are auto-converted to columns, row() requires the caller to supply the complete expression, so anything else raises TypeError with the qualified type name.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:11878

                raise ValueError(msg)
        elif index is not None and by_predicate is not None:
            msg = "cannot set both 'index' and 'by_predicate'; mutually exclusive"
            raise ValueError(msg)
        elif isinstance(index, pl.Expr):
            msg = "expressions should be passed to the `by_predicate` parameter"
            raise TypeError(msg)

        if index is not None:
            row = self._df.row_tuple(index)
            if named:
                return dict(zip(self.columns, row, strict=True))
            else:
                return row

        elif by_predicate is not None:
            if not isinstance(by_predicate, pl.Expr):
                msg = f"expected `by_predicate` to be an expression, got {qualified_type_name(by_predicate)!r}"
                raise TypeError(msg)
            rows = self.filter(by_predicate).rows()
            n_rows = len(rows)
            if n_rows > 1:
                msg = f"predicate <{by_predicate!s}> returned {n_rows} rows"
                raise TooManyRowsReturnedError(msg)
            elif n_rows == 0:
                msg = f"predicate <{by_predicate!s}> returned no rows"
                raise NoRowsReturnedError(msg)

            row = rows[0]
            if named:
                return dict(zip(self.columns, row, strict=True))
            else:
                return row
        else:
            msg = "one of `index` or `by_predicate` must be set"
            raise ValueError(msg)

View on GitHub (pinned to df599052da)

Solutions

  1. Build the full expression: df.row(by_predicate=pl.col('flag')) for a boolean column, or df.row(by_predicate=pl.col('id') == 42) for a comparison
  2. Combine conditions with & / | on expressions, not by passing multiple values
  3. If you have a boolean mask Series, filter first: df.filter(mask).row(0) — or rebuild it as an expression

Example fix

# before
row = df.row(by_predicate='id')  # or by_predicate=my_mask_series

# after
row = df.row(by_predicate=pl.col('id') == 42)
Defensive patterns

Strategy: type-guard

Validate before calling

from polars.expr import Expr

if not isinstance(by_predicate, Expr):
    raise TypeError(f'by_predicate must be a full pl.Expr, got {type(by_predicate)!r}; e.g. pl.col(id_col) == value')
row = df.row(by_predicate=by_predicate)

Type guard

from polars.expr import Expr

def is_row_predicate(v: object) -> bool:
    return isinstance(v, Expr)

Prevention

When it happens

Trigger: df.row(by_predicate='a'); df.row(by_predicate=('a', 'b')); df.row(by_predicate=pl.Series([True, False])); passing a string column name or a boolean mask instead of pl.col(...) == value.

Common situations: Expecting pandas-like boolean-mask indexing; passing just the column name hoping row() infers 'where this column is true'; converting dict/kwargs-based filter specs into row() calls.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/482745352ef24fe1. Report an issue: GitHub.