apache/iceberg · error · UnsupportedOperationException
In expression is not supported by the visitor
Error message
In expression is not supported by the visitor
What it means
The base expression visitor's default in(BoundReference, Set) throws UnsupportedOperationException because IN predicates are optional for visitors. It is thrown when a visitor that has not overridden the IN case encounters an in predicate. Visitors must opt in by overriding this method.
Source
Thrown at api/src/main/java/org/apache/iceberg/expressions/ExpressionVisitors.java:112
public <T> R gt(BoundReference<T> ref, Literal<T> lit) {
return null;
}
public <T> R gtEq(BoundReference<T> ref, Literal<T> lit) {
return null;
}
public <T> R eq(BoundReference<T> ref, Literal<T> lit) {
return null;
}
public <T> R notEq(BoundReference<T> ref, Literal<T> lit) {
return null;
}
public <T> R in(BoundReference<T> ref, Set<T> literalSet) {
throw new UnsupportedOperationException("In expression is not supported by the visitor");
}
public <T> R notIn(BoundReference<T> ref, Set<T> literalSet) {
throw new UnsupportedOperationException("notIn expression is not supported by the visitor");
}
public <T> R startsWith(BoundReference<T> ref, Literal<T> lit) {
throw new UnsupportedOperationException(
"startsWith expression is not supported by the visitor");
}
public <T> R notStartsWith(BoundReference<T> ref, Literal<T> lit) {
throw new UnsupportedOperationException(
"notStartsWith expression is not supported by the visitor");
}
/**
* Handle a non-reference value in this visitor.View on GitHub (pinned to 86d9c8fc54)
Solutions
- Override in(BoundReference<T> ref, Set<T> literalSet) in the visitor to translate/evaluate the IN predicate (often rewritten as a chain of OR equalities)
- Alternatively rewrite the expression with ExpressionUtil or rewriteNot/in expansion before visiting if the visitor only supports eq
- Update to a newer version of the evaluator/visitor implementation that supports IN
Example fix
// before
// visitor without in() hits default throw
// after
@Override
public <T> R in(BoundReference<T> ref, Set<T> literalSet) {
return literalSet.stream().map(v -> eqResult(ref, v)).reduce(or, combine); // or direct IN handling
} Defensive patterns
Strategy: try-catch
Validate before calling
// detect IN predicates before visiting
boolean hasIn = ExpressionVisitors.visit(expr, new ExpressionVisitors.ExpressionVisitor<Boolean>() {
@Override public Boolean predicate(UnboundPredicate<?> p) { return p.op() == Expression.Operation.IN; }
@Override public Boolean alwaysTrue() { return false; }
@Override public Boolean alwaysFalse() { return false; }
@Override public Boolean not(Boolean r) { return r; }
@Override public Boolean and(Boolean l, Boolean r) { return l || r; }
@Override public Boolean or(Boolean l, Boolean r) { return l || r; }
}); Type guard
static boolean isInPredicate(Predicate p) { return p.op() == Expression.Operation.IN; } Try / catch
try {
return visitor.in(ref, literalSet);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("In expression is not supported")) {
return expandInAsOr(ref, literalSet); // rewrite to OR of eq
}
throw e;
} Prevention
- Always override in() and notIn() together in custom visitors
- Rewrite user SQL filters containing IN clauses before passing them to old evaluators
- Pin visitor/evaluator implementations to an Iceberg version that supports IN predicates
When it happens
Trigger: Visiting an expression containing in(col, values) (e.g. from filter "col IN (...)") with a visitor class that does not override in(BoundReference<T>, Set<T>), such as a custom ExpressionVisitor base or an older evaluator predating IN support.
Common situations: Custom scan planners or predicate translators written before Iceberg added IN predicates; passing user SQL filters with IN clauses through an old visitor implementation.
Related errors
- ${className} does not implement notNaN
- notIn expression is not supported by the visitor
- startsWith expression is not supported by the visitor
- notStartsWith expression is not supported by the visitor
- Visitor %s does not support non-reference: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/443d5d81155ea23d.
Report an issue: GitHub.