{"record":{"id":"0c86363704690851","repo":"pola-rs/polars","slug":"predicate-by-predicate-s-returned-n-rows-row","errorCode":null,"errorMessage":"predicate <{by_predicate!s}> returned {n_rows} rows","messagePattern":"predicate <(.+?)> returned (.+?) rows","errorType":"exception","errorClass":"TooManyRowsReturnedError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/dataframe/frame.py","lineNumber":11883,"sourceCode":"            msg = \"expressions should be passed to the `by_predicate` parameter\"\n            raise TypeError(msg)\n\n        if index is not None:\n            row = self._df.row_tuple(index)\n            if named:\n                return dict(zip(self.columns, row, strict=True))\n            else:\n                return row\n\n        elif by_predicate is not None:\n            if not isinstance(by_predicate, pl.Expr):\n                msg = f\"expected `by_predicate` to be an expression, got {qualified_type_name(by_predicate)!r}\"\n                raise TypeError(msg)\n            rows = self.filter(by_predicate).rows()\n            n_rows = len(rows)\n            if n_rows > 1:\n                msg = f\"predicate <{by_predicate!s}> returned {n_rows} rows\"\n                raise TooManyRowsReturnedError(msg)\n            elif n_rows == 0:\n                msg = f\"predicate <{by_predicate!s}> returned no rows\"\n                raise NoRowsReturnedError(msg)\n\n            row = rows[0]\n            if named:\n                return dict(zip(self.columns, row, strict=True))\n            else:\n                return row\n        else:\n            msg = \"one of `index` or `by_predicate` must be set\"\n            raise ValueError(msg)\n\n    @overload\n    def rows(self, *, named: Literal[False] = ...) -> list[tuple[Any, ...]]: ...\n\n    @overload\n    def rows(self, *, named: Literal[True]) -> list[dict[str, Any]]: ...","sourceCodeStart":11865,"sourceCodeEnd":11901,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/dataframe/frame.py#L11865-L11901","documentation":"When DataFrame.row(by_predicate=expr) runs, the frame is filtered with the predicate and the number of surviving rows is counted. If more than one row matches, the call is ambiguous and polars raises TooManyRowsReturnedError (a polars.exceptions subclass), including the predicate text and the row count in the message.","triggerScenarios":"df.row(by_predicate=pl.col('category') == 'x') where several rows share the category; key lookups on data with duplicate keys (non-unique IDs, repeated timestamps); predicates that are always true, e.g. pl.col('flag') | ~pl.col('flag') or comparing against a value present in many rows.","commonSituations":"Reference/config tables that unexpectedly contain duplicate keys after an upstream merge or reload; time-series lookups where timestamps repeat; assuming a column is unique without a constraint.","solutions":["Make the predicate uniquely identifying — add conditions until exactly one row matches (composite key: (pl.col('a') == x) & (pl.col('b') == y))","If any match is acceptable, select deterministically: df.filter(pred).head(1).row(0) or .row(index=0) after sorting","Deduplicate the source or enforce uniqueness upstream (unique(subset=..., keep='first')) before doing key lookups","Catch polars.exceptions.TooManyRowsReturnedError to handle ambiguous keys explicitly"],"exampleFix":"# before\nrow = df.row(by_predicate=pl.col('user_id') == 7)  # duplicates -> TooManyRowsReturnedError\n\n# after\nrow = df.filter(pl.col('user_id') == 7).head(1).row(0)\n# or make the key unique:\n# row = df.row(by_predicate=(pl.col('user_id') == 7) & (pl.col('valid_to').is_null()))","handlingStrategy":"try-catch","validationCode":"matched = df.filter(by_predicate)\nif matched.height != 1:\n    raise ValueError(f'predicate matched {matched.height} rows; expected exactly 1')\nrow = matched.row(0)","typeGuard":null,"tryCatchPattern":"from polars.exceptions import TooManyRowsReturnedError\n\ntry:\n    row = df.row(by_predicate=pred)\nexcept TooManyRowsReturnedError:\n    # duplicate keys: pick deterministically or surface the ambiguity\n    matched = df.filter(pred).sort(key_col)\n    row = matched.head(1).row(0)","preventionTips":["Deduplicate lookup sources (unique(subset=key_cols, keep='first')) before key-based row() calls","Prefer composite-key predicates that are unique by construction","Where any-match suffices, use df.filter(pred).head(1).row(0) instead of row(by_predicate=...)"],"tags":["polars","dataframe","row","duplicate-keys","predicate","lookup"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}