{"record":{"id":"48d4bac75b5ac538","repo":"apache/iceberg","slug":"classname-does-not-implement-countfor-datafile","errorCode":null,"errorMessage":"${className} does not implement countFor(DataFile)","messagePattern":"(.+?) does not implement countFor\\(DataFile\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/CountAggregate.java","lineNumber":45,"sourceCode":"  }\n\n  @Override\n  public Long eval(StructLike struct) {\n    return countFor(struct);\n  }\n\n  @Override\n  public Long eval(DataFile file) {\n    return countFor(file);\n  }\n\n  protected Long countFor(StructLike row) {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement countFor(StructLike)\");\n  }\n\n  protected Long countFor(DataFile file) {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement countFor(DataFile)\");\n  }\n\n  @Override\n  public Aggregator<Long> newAggregator() {\n    return new CountAggregator<>(this);\n  }\n\n  private static class CountAggregator<T> extends NullSafeAggregator<T, Long> {\n    private Long count = 0L;\n\n    CountAggregator(BoundAggregate<T, Long> aggregate) {\n      super(aggregate);\n    }\n\n    @Override\n    protected void update(Long value) {\n      count += value;","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/CountAggregate.java#L27-L63","documentation":"The DataFile overload of CountAggregate.countFor is likewise a stub throwing UnsupportedOperationException. Concrete subclasses must override countFor(DataFile) to compute counts from file metadata. Evaluating the aggregate with a DataFile evaluator on a subclass lacking that override throws this.","triggerScenarios":"Calling eval(DataFile) or countFor(DataFile) on a CountAggregate subclass that only implemented countFor(StructLike).","commonSituations":"Running aggregate expressions during scan planning (which evaluates against DataFile objects) with an aggregate subclass implemented only for row-level evaluation.","solutions":["Override countFor(DataFile) in the CountAggregate subclass","Restrict evaluation to row-based paths if only the StructLike variant exists","Check the aggregate's supported evaluation mode before choosing the evaluator"],"exampleFix":"// before\nclass MyCount extends CountAggregate<Void> { /* only countFor(StructLike) overridden */ }\n// after\nclass MyCount extends CountAggregate<Void> {\n  @Override\n  protected Long countFor(DataFile file) { return file.recordCount(); }\n}","handlingStrategy":"validation","validationCode":"// ensure the subclass implements the DataFile path before scan-planning evaluation\nif (!implementsDataFileCount(agg)) { throw new IllegalStateException(\"subclass must override countFor(DataFile)\"); }","typeGuard":"boolean supportsFileEval = !(agg instanceof CountAggregate) || overridesCountForDataFile(agg);","tryCatchPattern":"try { return agg.eval(dataFile); } catch (UnsupportedOperationException e) { /* fall back to row-based evaluation or skip metric pushdown */ }","preventionTips":["Override countFor(DataFile) in CountAggregate subclasses used during scan planning","Only use file-metric aggregates in file-evaluation contexts","Test aggregates against both evaluator paths"],"tags":["expressions","aggregate","unsupported-operation"],"backgroundTag":"method-not-implemented","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}