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

  1. Check predicate.isLiteralPredicate() before calling asLiteralPredicate()
  2. Handle each predicate kind in order: isUnaryPredicate(), isLiteralPredicate(), isSetPredicate()
  3. 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

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


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)