apache/iceberg · error · IllegalStateException
Invalid operation for BoundUnaryPredicate:
Error message
Invalid operation for BoundUnaryPredicate:
What it means
BoundUnaryPredicate.test() supports only IS_NULL, NOT_NULL, IS_NAN and NOT_NAN operations. Any other operation reaches the default branch and throws IllegalStateException. A BoundUnaryPredicate should never hold other operations, so this signals corrupted construction or an unsafe rewrite.
Solutions
- Only assign unary operations (IS_NULL, NOT_NULL, IS_NAN, NOT_NAN) to BoundUnaryPredicate
- Check op() before calling test() in generic evaluation code
- Report a bug if this fires with unmodified Iceberg APIs
Example fix
// before
unaryPred.test(row.get(pos, type));
// after
switch (unaryPred.op()) {
case IS_NULL: case NOT_NULL: case IS_NAN: case NOT_NAN:
unaryPred.test(row.get(pos, type));
break;
}
Defensive patterns
Strategy: validation
Validate before calling
Set<Operation> OK = Set.of(Operation.IS_NULL, Operation.NOT_NULL, Operation.IS_NAN, Operation.NOT_NAN); if (!OK.contains(pred.op())) { throw new IllegalArgumentException("BoundUnaryPredicate requires a unary op"); } Type guard
boolean evaluableUnary = pred.op() == Operation.IS_NULL || pred.op() == Operation.NOT_NULL || pred.op() == Operation.IS_NAN || pred.op() == Operation.NOT_NAN;
Try / catch
try { result = unaryPred.test(value); } catch (IllegalStateException e) { /* corrupt operation: log and fail fast */ } Prevention
- Only attach unary operations to BoundUnaryPredicate
- Rebuild predicates after rewrites rather than mutating operations
- Fail fast on unexpected op() in generic evaluators
When it happens
Trigger: Evaluating a BoundUnaryPredicate whose op() is something other than the four supported unary operations — only possible through misuse of internal constructors or custom rewrites.
Common situations: Custom expression transformation code that mutates operations without matching the predicate class to the operation kind.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Invalid operation for BoundSetPredicate:
- 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/fd031bf4d955bc13.
Report an issue: GitHub.
Appendix: source
Thrown at api/src/main/java/org/apache/iceberg/expressions/BoundUnaryPredicate.java:55
@Override
public BoundUnaryPredicate<T> asUnaryPredicate() {
return this;
}
@Override
public boolean test(T value) {
switch (op()) {
case IS_NULL:
return value == null;
case NOT_NULL:
return value != null;
case IS_NAN:
return NaNUtil.isNaN(value);
case NOT_NAN:
return !NaNUtil.isNaN(value);
default:
throw new IllegalStateException("Invalid operation for BoundUnaryPredicate: " + op());
}
}
@Override
public boolean isEquivalentTo(Expression other) {
if (op() == other.op()) {
return term().isEquivalentTo(((BoundUnaryPredicate<?>) other).term());
}
return false;
}
@Override
public String toString() {
switch (op()) {
case IS_NULL:
return "is_null(" + term() + ")";
case NOT_NULL:View on GitHub (pinned to 86d9c8fc54)