pola-rs/polars · error

can only call `.row()` without "index" or "by_predicate" val

Error message

can only call `.row()` without "index" or "by_predicate" values if the DataFrame has a single row; shape={self.shape!r}

What it means

DataFrame.row(index=None, by_predicate=None) returns a single row; calling it with no arguments is only allowed when the frame has exactly one row (then that row is returned via index=0). On any other height the choice of 'the' row is ambiguous, so polars raises ValueError and includes the frame's shape in the message.

Source

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

        names to row values.

        >>> df.row(2, named=True)
        {'foo': 3, 'bar': 8, 'ham': 'c'}

        Use `by_predicate` to return the row that matches the given predicate.

        >>> df.row(by_predicate=(pl.col("ham") == "b"))
        (2, 7, 'b')
        """
        if index is None and by_predicate is None:
            if self.height == 1:
                index = 0
            else:
                msg = (
                    'can only call `.row()` without "index" or "by_predicate" values '
                    f"if the DataFrame has a single row; shape={self.shape!r}"
                )
                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)

View on GitHub (pinned to df599052da)

Solutions

  1. Pass an explicit selector: df.row(index=0) for the first row, or df.row(by_predicate=pl.col('id') == value) for a key match
  2. Guard the call when single-row is the expectation: if df.height == 1: row = df.row()
  3. If multiple matches are legitimate, take one deterministically: df.filter(pred).head(1).row(0), or use .rows() for all of them
  4. For key lookups, assert uniqueness first: assert df.filter(pl.col('id') == value).height == 1

Example fix

# before
row = df.row()  # ValueError when df.height != 1

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

Strategy: validation

Validate before calling

if df.height != 1:
    raise ValueError(f'expected exactly one row, got {df.height}')
row = df.row()

Prevention

When it happens

Trigger: df.row() where df.height != 1: multi-row frames (most common), empty frames (height 0), or frames after unique/filter/group_by-head operations that unexpectedly changed cardinality.

Common situations: Fetching 'the' row after filtering on what was assumed to be a unique key (config/version lookups, ID fetch) when duplicates actually exist; calling row() on an empty result set; using row() on output of a search helper that can return several hits.

Related errors


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