{"record":{"id":"77d167088394f9a8","repo":"apache/beam","slug":"unexpected-content-type-for-deletefile","errorCode":null,"errorMessage":"Unexpected content type for DeleteFile: {}","messagePattern":"Unexpected content type for DeleteFile: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/SerializableDeleteFile.java","lineNumber":327,"sourceCode":"          for (int i = 0; i < fieldIds.size(); i++) {\n            equalityFieldIds[i] = fieldIds.get(i);\n          }\n        }\n        SortOrder sortOrder = SortOrder.unsorted();\n        if (sortOrders != null) {\n          sortOrder =\n              checkStateNotNull(\n                  sortOrders.get(getSortOrderId()),\n                  \"This DeleteFile was originally created with sort order id '%s', \"\n                      + \"but table only has sort order ids: %s.\",\n                  getSortOrderId(),\n                  sortOrders.keySet());\n        }\n        deleteFileBuilder =\n            deleteFileBuilder.ofEqualityDeletes(equalityFieldIds).withSortOrder(sortOrder);\n        break;\n      default:\n        throw new IllegalStateException(\n            \"Unexpected content type for DeleteFile: \" + getContentType());\n    }\n\n    // contentOffset / contentSizeInBytes really are Puffin-only: build() rejects a non-null value\n    // for either on any other format, and requires both (plus referencedDataFile) on Puffin.\n    if (getFileFormat().equalsIgnoreCase(FileFormat.PUFFIN.name())) {\n      deleteFileBuilder =\n          deleteFileBuilder\n              .withContentOffset(checkStateNotNull(getContentOffset()))\n              .withContentSizeInBytes(checkStateNotNull(getContentSizeInBytes()));\n    }\n    return deleteFileBuilder.build();\n  }\n\n  private StructLike partition(PartitionSpec spec) {\n    return (StructLike)\n        SingleValueParser.fromJson(spec.partitionType(), checkStateNotNull(getJsonPartition()));\n  }","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/SerializableDeleteFile.java#L309-L345","documentation":"SerializableDeleteFile.createDeleteFile() rebuilds a DeleteFile from its serialized form and switches on the content type (POSITION_DELETES, EQUALITY_DELETES, etc.). An unknown content type falls into the default branch and throws IllegalStateException. This indicates corrupted or future-version serialization data the current connector cannot reconstruct.","triggerScenarios":"Deserializing a SerializableDeleteFile whose getContentType() is not a recognized DeleteFile content type, e.g. data serialized by a newer Iceberg/Beam version adding a new content type, or hand-edited/corrupted serialized state.","commonSituations":"Mixing Beam connector versions across pipeline stages (old writer, new reader) or vice versa; restoring a checkpoint/Fusion state produced by a different library version; manual modification of serialized JSON fields.","solutions":["Pin a single version of the Beam IO iceberg connector across all pipeline stages and workers.","Inspect the serialized contentType value to identify where the unexpected value originated.","Re-serialize affected state with the current library version.","If a new content type is legitimate, add a builder branch for it in createDeleteFile()."],"exampleFix":"// before\n// running pipeline with beam-sdks-java-io-iceberg 2.61 workers after writing state with 2.63\n// after\n// align versions everywhere\n// implementation 'org.apache.beam:beam-sdks-java-io-iceberg:2.63.0' // same version on writer and reader","handlingStrategy":"try-catch","validationCode":"// check serialization compatibility before deserializing\nif (!KNOWN_CONTENT_TYPES.contains(serializableDeleteFile.getContentType())) {\n  throw new IllegalStateException(\"Unknown DeleteFile content type: \" + serializableDeleteFile.getContentType());\n}","typeGuard":null,"tryCatchPattern":"try {\n  DeleteFile df = SerializableDeleteFile.reconstruct(serialized);\n} catch (IllegalStateException e) {\n  throw new IllegalStateException(\"Incompatible serialized delete file (version mismatch?): \" + e.getMessage(), e);\n}","preventionTips":["Use one Beam connector version for all pipeline stages and workers.","Avoid manually editing serialized JSON fields of SerializableDeleteFile.","Test checkpoint/state round-trips when upgrading library versions."],"tags":["iceberg","java","deserialization","state","apache-beam"],"backgroundTag":"unexpected-response-shape","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}