apache/iceberg · error · UnsupportedOperationException
Cannot evaluate
Error message
Cannot evaluate
What it means
BoundExtract represents an extract expression (pulling a value from a variant/object by path). Its eval(StructLike) has no general implementation, so calling it throws UnsupportedOperationException. Extract expressions must be resolved/lowered by the engine before evaluation.
Source
Thrown at api/src/main/java/org/apache/iceberg/expressions/BoundExtract.java:61
@Override
public Type type() {
return type;
}
@Override
public boolean isEquivalentTo(BoundTerm<?> other) {
if (other instanceof BoundExtract) {
BoundExtract<?> that = (BoundExtract<?>) other;
return ref.isEquivalentTo(that.ref) && path.equals(that.path) && type.equals(that.type);
}
return false;
}
@Override
public T eval(StructLike struct) {
throw new UnsupportedOperationException("Cannot evaluate " + this);
}
@Override
public String toString() {
return "extract(" + ref + ", path=" + path + ", type=" + type + ")";
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Lower extract expressions into engine-native evaluation before binding/evaluating
- Filter out extract expressions from pure Iceberg row evaluation paths
- Use ExpressionVisitors to detect BoundExtract and handle it specially
- Upgrade Iceberg to a version with engine support for the extract operation
Example fix
// before
Object v = boundExtract.eval(rowStruct); // throws
// after
if (boundExtract instanceof BoundExtract) {
// handle via engine-specific variant accessor, not generic eval
return;
}
Object v = expr.eval(rowStruct); Defensive patterns
Strategy: type-guard
Validate before calling
if (expr instanceof BoundExtract) { /* route to variant-capable evaluator */ } Type guard
boolean isExtract = expr instanceof BoundExtract;
Try / catch
try { v = expr.eval(struct); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("Cannot evaluate")) { /* lower to engine-native evaluation */ } else { throw e; } } Prevention
- Detect BoundExtract via visitors before generic evaluation
- Lower extract expressions into engine-native code paths
- Keep extract expressions out of pure-core row evaluation
When it happens
Trigger: Calling eval(StructLike) directly on a BoundExtract expression instead of letting the scan/residual machinery handle it; binding an extract expression and trying row evaluation.
Common situations: Variant-type filter pushdown where the engine must interpret the extract path; custom evaluators encountering extract expressions they cannot lower.
Related errors
- Invalid aggregate:
- does not implement eval(StructLike)
- does not implement eval(DataFile)
- does not implement hasValue(DataFile)
- does not implement newAggregator()
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/27fa62d8eaeaf242.
Report an issue: GitHub.