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 NoneView on GitHub (pinned to df599052da)
Solutions
- Skip the filter call when the predicate list is empty: lf = lf.filter(*preds) if preds else lf
- Supply at least one predicate or a keyword constraint (lf.filter(col=val))
- 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
- Guard dynamic filter construction with an emptiness check
- Default config-driven filter lists to at least one trivially-true rule if a no-op is desired
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
- invalid predicate for `filter`: {err}
- selecting rows by passing a boolean mask to `__getitem__` is
- at least one predicate or constraint must be provided
- negative stop is not supported for lazy slices
- negative stride is not supported in conjunction with start+s
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/00215b1f9feb1b0a.
Report an issue: GitHub.