pola-rs/polars · error · TypeError

the truth value of a DataFrame is ambiguous Hint: to check

Error message

the truth value of a DataFrame is ambiguous

Hint: to check if a DataFrame contains any values, use `is_empty()`.

What it means

Python calls DataFrame.__bool__ whenever a DataFrame is used in a boolean context (if, while, and/or/not, bool(), filter()). Truthiness for a 2-D table is undefined — empty? any true? all true? — so polars raises TypeError and the message points to is_empty() for the most common intent. This mirrors NumPy's ambiguous-truth error.

Source

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

    def _cast_all_from_to(
        self, df: DataFrame, from_: frozenset[PolarsDataType], to: PolarsDataType
    ) -> DataFrame:
        casts = [s.cast(to).alias(s.name) for s in df if s.dtype in from_]
        return df.with_columns(casts) if casts else df

    def __floordiv__(self, other: DataFrame | Series | int | float) -> DataFrame:
        return self._div(other, floordiv=True)

    def __truediv__(self, other: DataFrame | Series | int | float) -> DataFrame:
        return self._div(other, floordiv=False)

    def __bool__(self) -> NoReturn:
        msg = (
            "the truth value of a DataFrame is ambiguous"
            "\n\nHint: to check if a DataFrame contains any values, use `is_empty()`."
        )
        raise TypeError(msg)

    def __eq__(self, other: object) -> DataFrame:  # type: ignore[override]
        return self._comp(other, "eq")

    def __ne__(self, other: object) -> DataFrame:  # type: ignore[override]
        return self._comp(other, "neq")

    def __gt__(self, other: Any) -> DataFrame:
        return self._comp(other, "gt")

    def __lt__(self, other: Any) -> DataFrame:
        return self._comp(other, "lt")

    def __ge__(self, other: Any) -> DataFrame:
        return self._comp(other, "gt_eq")

    def __le__(self, other: Any) -> DataFrame:
        return self._comp(other, "lt_eq")

View on GitHub (pinned to df599052da)

Solutions

  1. Use df.is_empty() to test for no rows
  2. Use df.height > 0 or len(df) > 0 for 'has data'
  3. In tests, assert on content: assert df.height == 3 or polars.testing.assert_frame_equal
  4. For 'any/all cell true', materialize first: (df == expected).all().all_horizontal().item() or df.select(pl.all().any()).row(0)

Example fix

# before
if df:
    process(df)

# after
if not df.is_empty():
    process(df)
Defensive patterns

Strategy: validation

Validate before calling

if df.is_empty():
    print('no rows')
elif df.height > 0:
    print(f'{df.height} rows')

Prevention

When it happens

Trigger: if df: / while df: / not df; df and other or default; bool(df); using df as a predicate in filter(df); assert df (in tests); ternaries like x if df else y.

Common situations: Pandas habits where `if df.empty:` or truthy shortcuts were common; checking 'did the query return anything' after a filter/join; test assertions like `assert result_df`; default-value patterns df or pl.DataFrame().

Related errors


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