apache/iceberg · error · UnsupportedOperationException
does not implement hasValue(DataFile)
Error message
does not implement hasValue(DataFile)
What it means
hasValue(DataFile) indicates whether a data file's metrics contain a value the aggregate can use; the base BoundAggregate stub always throws. Subclasses not supporting file-level metrics evaluation trigger this UnsupportedOperationException.
Source
Thrown at api/src/main/java/org/apache/iceberg/expressions/BoundAggregate.java:45
public class BoundAggregate<T, C> extends Aggregate<BoundTerm<T>> implements Bound<C> {
protected BoundAggregate(Operation op, BoundTerm<T> term) {
super(op, term);
}
@Override
public C eval(StructLike struct) {
throw new UnsupportedOperationException(
this.getClass().getName() + " does not implement eval(StructLike)");
}
C eval(DataFile file) {
throw new UnsupportedOperationException(
this.getClass().getName() + " does not implement eval(DataFile)");
}
boolean hasValue(DataFile file) {
throw new UnsupportedOperationException(
this.getClass().getName() + " does not implement hasValue(DataFile)");
}
Aggregator<C> newAggregator() {
throw new UnsupportedOperationException(
this.getClass().getName() + " does not implement newAggregator()");
}
boolean containsNan(DataFile file, int fieldId) {
Long nanCount = safeGet(file.nanValueCounts(), fieldId);
return nanCount != null && nanCount > 0;
}
@Override
public BoundReference<?> ref() {
return term().ref();
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Guard with try-catch or check op() type before calling hasValue
- Use AggregateEvaluator's supported aggregates for file pruning
- Override hasValue(DataFile) in custom subclasses
- Default to assuming a value exists (no pruning) when unsupported
Example fix
// before boolean has = agg.hasValue(dataFile); // throws // after boolean has = agg.op() == Operation.COUNT || agg.evalHasValue(dataFile); // route via supported path
Defensive patterns
Strategy: try-catch
Validate before calling
boolean supported = Set.of(Operation.COUNT, Operation.MAX, Operation.MIN).contains(agg.op());
Try / catch
try { has = agg.hasValue(dataFile); } catch (UnsupportedOperationException e) { has = true; /* assume value present, skip pruning */ } Prevention
- Check op() support before probing hasValue
- Treat unsupported aggregates as non-prunable
- Wrap file-pruning loops with safe fallbacks
When it happens
Trigger: Calling hasValue(DataFile) on a BoundAggregate subclass lacking file-metrics support, typically during file pruning with aggregate pushdown.
Common situations: Custom pruning implementations probing metrics for aggregate types that do not support them; API evolution where new aggregates lag behind file-level support.
Related errors
- does not implement eval(StructLike)
- does not implement eval(DataFile)
- does not implement newAggregator()
- Invalid aggregate:
- Found already bound aggregate:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/dc3ba91b3bc0dd3a.
Report an issue: GitHub.