apache/iceberg · error · IllegalStateException
Not a literal predicate:
Error message
Not a literal predicate:
What it means
BoundPredicate is the base class for bound predicates; only BoundLiteralPredicate represents a comparison against a single literal. asLiteralPredicate() is a narrowing accessor that throws IllegalStateException when called on a predicate that is not a literal predicate (e.g. unary or set predicates). Call isLiteralPredicate() first to check before narrowing.
Solutions
- Check predicate.isLiteralPredicate() before calling asLiteralPredicate()
- Handle each predicate kind in order: isUnaryPredicate(), isLiteralPredicate(), isSetPredicate()
- Bind the expression first with Binder.bind(schema, expr); unbound predicates are not literal predicates
Example fix
// before
BoundLiteralPredicate<?> lit = (BoundLiteralPredicate) boundPred.asLiteralPredicate();
// after
if (boundPred.isLiteralPredicate()) {
BoundLiteralPredicate<?> lit = boundPred.asLiteralPredicate();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!pred.isLiteralPredicate()) { throw new IllegalArgumentException("expected literal predicate, got " + pred.op()); } Type guard
function asLit(p) { return p.isLiteralPredicate() ? p.asLiteralPredicate() : null; } Try / catch
try { lit = pred.asLiteralPredicate(); } catch (IllegalStateException e) { /* handle non-literal predicate */ } Prevention
- Always call isLiteralPredicate() before asLiteralPredicate()
- Branch on isUnaryPredicate/isLiteralPredicate/isSetPredicate in visitors
- Bind expressions before inspecting predicate types
When it happens
Trigger: Calling asLiteralPredicate() on a BoundPredicate whose concrete type is BoundUnaryPredicate or BoundSetPredicate, typically after binding an expression via Binder.bind() and iterating predicate nodes in a visitor.
Common situations: Custom expression visitors that rewrite or evaluate bound expressions and assume every bound predicate is a literal comparison; forgot to branch on isLiteralPredicate()/isSetPredicate()/isUnaryPredicate() first.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Not a set predicate:
- AboveMax has no comparator
- BelowMin has no comparator
- BelowMin has no value
- Cannot change the type of BelowMin
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/3dd9c1e1d49d8037.
Report an issue: GitHub.
Appendix: source
Thrown at api/src/main/java/org/apache/iceberg/expressions/BoundPredicate.java:58
@Override
public BoundReference<?> ref() {
return term().ref();
}
public boolean isUnaryPredicate() {
return false;
}
public BoundUnaryPredicate<T> asUnaryPredicate() {
throw new IllegalStateException("Not a unary predicate: " + this);
}
public boolean isLiteralPredicate() {
return false;
}
public BoundLiteralPredicate<T> asLiteralPredicate() {
throw new IllegalStateException("Not a literal predicate: " + this);
}
public boolean isSetPredicate() {
return false;
}
public BoundSetPredicate<T> asSetPredicate() {
throw new IllegalStateException("Not a set predicate: " + this);
}
}
View on GitHub (pinned to 86d9c8fc54)