{"record":{"id":"c3ddde7b18ce859b","repo":"apache/iceberg","slug":"unsupported-delete-granularity-granularity-c3ddde","errorCode":null,"errorMessage":"Unsupported delete granularity: <granularity>","messagePattern":"Unsupported delete granularity: <granularity>","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/io/ClusteredPositionDeleteWriter.java","lineNumber":79,"sourceCode":"    this.writerFactory = writerFactory;\n    this.fileFactory = fileFactory;\n    this.io = io;\n    this.targetFileSizeInBytes = targetFileSizeInBytes;\n    this.granularity = granularity;\n    this.deleteFiles = Lists.newArrayList();\n    this.referencedDataFiles = CharSequenceSet.empty();\n  }\n\n  @Override\n  protected FileWriter<PositionDelete<T>, DeleteWriteResult> newWriter(\n      PartitionSpec spec, StructLike partition) {\n    switch (granularity) {\n      case FILE:\n        return new FileScopedPositionDeleteWriter<>(() -> newRollingWriter(spec, partition));\n      case PARTITION:\n        return newRollingWriter(spec, partition);\n      default:\n        throw new UnsupportedOperationException(\"Unsupported delete granularity: \" + granularity);\n    }\n  }\n\n  private RollingPositionDeleteWriter<T> newRollingWriter(\n      PartitionSpec spec, StructLike partition) {\n    return new RollingPositionDeleteWriter<>(\n        writerFactory, fileFactory, io, targetFileSizeInBytes, spec, partition);\n  }\n\n  @Override\n  protected void addResult(DeleteWriteResult result) {\n    deleteFiles.addAll(result.deleteFiles());\n    referencedDataFiles.addAll(result.referencedDataFiles());\n  }\n\n  @Override\n  protected DeleteWriteResult aggregatedResult() {\n    return new DeleteWriteResult(deleteFiles, referencedDataFiles);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/io/ClusteredPositionDeleteWriter.java#L61-L97","documentation":"ClusteredPositionDeleteWriter.newWriter only supports FILE and PARTITION delete granularities; any other DeleteGranularity value (e.g., null or a new enum constant from a newer Iceberg version) hits the default branch and throws UnsupportedOperationException.","triggerScenarios":"Constructing ClusteredPositionDeleteWriter with a DeleteGranularity other than FILE or PARTITION — typically passing null, or an enum constant introduced in a later version while running with an older writer switch.","commonSituations":"Custom writer code wiring up a DeleteGranularity from config where the mapping/validation step is missing; version skew between a job config that requests a newer granularity and the library version in the classpath.","solutions":["Pass DeleteGranularity.FILE or DeleteGranularity.PARTITION explicitly when constructing the writer.","Validate/normalize the granularity from configuration before constructing the writer, defaulting to FILE.","Align library versions if the granularity constant comes from a newer Iceberg release."],"exampleFix":"// before\nDeleteGranularity g = confValue; // may be null\nnew ClusteredPositionDeleteWriter<>(factory, g, spec);\n// after\nDeleteGranularity g = confValue == null ? DeleteGranularity.FILE : confValue;","handlingStrategy":"validation","validationCode":"Preconditions.checkArgument(g == DeleteGranularity.FILE || g == DeleteGranularity.PARTITION, \"unsupported granularity\");","typeGuard":"static boolean supported(DeleteGranularity g) { return g == DeleteGranularity.FILE || g == DeleteGranularity.PARTITION; }","tryCatchPattern":"try {\n  writer.write(...);\n} catch (UnsupportedOperationException e) {\n  // reconstruct writer with FILE granularity\n}","preventionTips":["Never pass null or unvalidated config values as DeleteGranularity.","Default unknown granularity values to FILE at config parsing time.","Keep library versions aligned when using newer enum constants."],"tags":["unsupported-operation","enum","delete-files","writer"],"backgroundTag":"unsupported-enum-value","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"}