pola-rs/polars · error · NoRowsReturnedError
predicate <{by_predicate!s}> returned no rows
Error message
predicate <{by_predicate!s}> returned no rows What it means
When DataFrame.row(by_predicate=expr) filters the frame and zero rows survive, polars raises NoRowsReturnedError (a polars.exceptions subclass) with the predicate text. This is the empty counterpart of TooManyRowsReturnedError and typically indicates the looked-up value does not exist (or the predicate never matches) rather than a programming mistake.
Source
Thrown at py-polars/src/polars/dataframe/frame.py:11886
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)
@overload
def rows(self, *, named: Literal[False] = ...) -> list[tuple[Any, ...]]: ...
@overload
def rows(self, *, named: Literal[True]) -> list[dict[str, Any]]: ...
def rows(
self, *, named: bool = FalseView on GitHub (pinned to df599052da)
Solutions
- Verify existence first: matched = df.filter(pred); use matched only if matched.height == 1
- Check the comparison value's dtype and semantics (cast, strptime, dt.convert_time_zone) if matches are expected but absent
- For optional lookups, catch polars.exceptions.NoRowsReturnedError and return a default/fallback
- Handle nulls explicitly (fill_null / is_null()) since comparisons against null never match
Example fix
# before
row = df.row(by_predicate=pl.col('id') == 42) # NoRowsReturnedError
# after
matched = df.filter(pl.col('id') == 42)
row = matched.row(0) if matched.height == 1 else None Defensive patterns
Strategy: try-catch
Validate before calling
matched = df.filter(by_predicate)
if matched.is_empty():
row = None # or raise your own NotFound error with context
else:
row = matched.row(0) Try / catch
from polars.exceptions import NoRowsReturnedError
try:
row = df.row(by_predicate=pred)
except NoRowsReturnedError:
row = None # optional lookup: fall back to a default Prevention
- Check existence with df.filter(pred).height before one-row lookups on external/sparse data
- Verify comparison dtype and semantics (cast, timezone, strptime) when matches are expected but absent
- Remember null never equals anything — handle nulls with is_null()/fill_null() in predicates
When it happens
Trigger: df.row(by_predicate=pl.col('id') == 42) when no row has id 42; comparing with the wrong dtype or value (string vs int, naive vs timezone-aware datetimes); predicates on an empty frame; NULL-containing keys (comparisons with null never match).
Common situations: Key lookups for ids missing from the current snapshot; date-range lookups that miss due to timezone/precision; lookup tables loaded with filters that excluded the needed rows; empty input files in pipelines.
Related errors
- predicate <{by_predicate!s}> returned {n_rows} rows
- can only call `.row()` without "index" or "by_predicate" val
- cannot set both 'index' and 'by_predicate'; mutually exclusi
- expressions should be passed to the `by_predicate` parameter
- expected `by_predicate` to be an expression, got {qualified_
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/9c8bd1e5b1f0bf09.
Report an issue: GitHub.