pola-rs/polars · error · TypeError

at least one predicate or constraint must be provided

Error message

at least one predicate or constraint must be provided

What it means

LazyFrame.filter() raises TypeError when it ends up with no predicates at all — no positional predicates, no keyword equality constraints, and no boolean masks. This typically happens when predicates are built dynamically and the list comes back empty, rather than from an explicit literal call.

Source

Thrown at py-polars/src/polars/lazyframe/frame.py:4707

                err = (
                    f"Series(…, dtype={p.dtype})"
                    if isinstance(p, pl.Series)
                    else repr(p)
                )
                msg = f"invalid predicate for `filter`: {err}"
                raise TypeError(msg)
            else:
                all_predicates.extend(
                    wrap_expr(x) for x in parse_into_list_of_expressions(p)
                )

        # unpack equality constraints from kwargs
        all_predicates.extend(
            F.col(name).eq(value) for name, value in constraints.items()
        )
        if not (all_predicates or boolean_masks):
            msg = "at least one predicate or constraint must be provided"
            raise TypeError(msg)

        # if multiple predicates, combine as 'horizontal' expression
        combined_predicate = (
            (
                F.all_horizontal(*all_predicates)
                if len(all_predicates) > 1
                else all_predicates[0]
            )
            if all_predicates
            else None
        )

        # apply reduced boolean mask first, if applicable, then predicates
        if boolean_masks:
            mask_expr = F.lit(reduce(and_, boolean_masks))
            combined_predicate = (
                mask_expr
                if combined_predicate is None

View on GitHub (pinned to df599052da)

Solutions

  1. Skip the filter call when the predicate list is empty: lf = lf.filter(*preds) if preds else lf
  2. Supply at least one predicate or a keyword constraint (lf.filter(col=val))
  3. Default to an always-true expression if a no-op filter is intended: lf.filter(pl.lit(True))

Example fix

# before
preds = build_predicates(cfg)  # may be []
lf = lf.filter(*preds)

# after
preds = build_predicates(cfg)
if preds:
    lf = lf.filter(*preds)
Defensive patterns

Strategy: validation

Validate before calling

if not preds and not constraints:
    lf_result = lf  # no-op instead of error
else:
    lf_result = lf.filter(*preds, **constraints)

Type guard

def has_any_predicate(preds, constraints) -> bool:
    return bool(preds) or bool(constraints)

Prevention

When it happens

Trigger: predicates = [p for p in candidates if p]; lf.filter(*predicates) with an empty result; lf.filter() called with no args inside a generic pipeline; all predicates filtered out by a condition.

Common situations: Config-driven filtering where no filter rules are enabled; data pipelines that apply filters conditionally; refactors that leave a bare filter() call.

Related errors


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