{"record":{"id":"6c28724fc0543bae","repo":"apache/beam","slug":"unknown-changelogscantask-type-serializablechangelogtask","errorCode":null,"errorMessage":"Unknown ChangelogScanTask type: {}","messagePattern":"Unknown ChangelogScanTask type: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/cdc/SerializableChangelogTask.java","lineNumber":191,"sourceCode":"                  toSerializableDeletes(addedRowsTask.deletes(), specs, includeMetrics));\n    } else if (task instanceof DeletedRowsScanTask) {\n      DeletedRowsScanTask deletedRowsTask = (DeletedRowsScanTask) task;\n      builder =\n          builder\n              .setType(Type.DELETED_ROWS)\n              .setAddedDeletes(\n                  toSerializableDeletes(deletedRowsTask.addedDeletes(), specs, includeMetrics))\n              .setExistingDeletes(\n                  toSerializableDeletes(deletedRowsTask.existingDeletes(), specs, includeMetrics));\n    } else if (task instanceof DeletedDataFileScanTask) {\n      DeletedDataFileScanTask deletedFileTask = (DeletedDataFileScanTask) task;\n      builder =\n          builder\n              .setType(Type.DELETED_FILE)\n              .setExistingDeletes(\n                  toSerializableDeletes(deletedFileTask.existingDeletes(), specs, includeMetrics));\n    } else {\n      throw new IllegalStateException(\"Unknown ChangelogScanTask type: \" + task.getClass());\n    }\n    return builder.build();\n  }\n\n  static Type getType(ChangelogScanTask task) {\n    if (task instanceof AddedRowsScanTask) {\n      return Type.ADDED_ROWS;\n    } else if (task instanceof DeletedRowsScanTask) {\n      return Type.DELETED_ROWS;\n    } else if (task instanceof DeletedDataFileScanTask) {\n      return Type.DELETED_FILE;\n    } else {\n      throw new IllegalStateException(\"Unknown ChangelogScanTask type: \" + task.getClass());\n    }\n  }\n\n  static long getTotalLength(List<ChangelogScanTask> tasks) {\n    return tasks.stream().mapToLong(SerializableChangelogTask::getLength).sum();","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/cdc/SerializableChangelogTask.java#L173-L209","documentation":"SerializableChangelogTask.from serializes a ChangelogScanTask into a portable form by branching on the task's concrete type. If getType(task) yields a Type the switch does not handle (a ChangelogScanTask subtype outside the four supported ones), it throws IllegalStateException. This guards against new Iceberg changelog task types appearing without a serialization path.","triggerScenarios":"Calling SerializableChangelogTask.from(task) with a ChangelogScanTask that is not an AddedRowsScanTask, DeletedRowsScanTask, DeletedDataFileScanTask, or the type mapped by getType — e.g. a new task subtype introduced by a newer Iceberg incremental scan.","commonSituations":"Iceberg library upgrade adding a new ChangelogScanTask subtype; a custom ChangelogScanTask implementation passed into the Beam CDC pipeline; mismatch between getType's classification and the serialization switch after partial code changes.","solutions":["Ensure only Iceberg versions producing the four supported task types are used","Extend both getType() and from() to handle the new task subtype","Validate task types before serialization and fail with a clear pipeline-level error","Pin/align the Iceberg runtime version with the one Beam's CDC was built against"],"exampleFix":"// before\nSerializableChangelogTask t = SerializableChangelogTask.from(unknownTask, specs, true);\n// after\nif (!SerializableChangelogTask.isSupported(unknownTask)) {\n  throw new IllegalArgumentException(\"Unsupported task type: \" + unknownTask.getClass());\n}\nSerializableChangelogTask t = SerializableChangelogTask.from(unknownTask, specs, true);","handlingStrategy":"type-guard","validationCode":"if (!(task instanceof AddedRowsScanTask)\n    && !(task instanceof DeletedRowsScanTask)\n    && !(task instanceof DeletedDataFileScanTask)) {\n  throw new IllegalArgumentException(\"Unsupported changelog task type: \" + task.getClass());\n}","typeGuard":"static boolean isSerializableTask(ChangelogScanTask task) {\n  return task instanceof AddedRowsScanTask\n      || task instanceof DeletedRowsScanTask\n      || task instanceof DeletedDataFileScanTask;\n}","tryCatchPattern":"try {\n  SerializableChangelogTask t = SerializableChangelogTask.from(task, specs, includeMetrics);\n} catch (IllegalStateException e) {\n  throw new UnsupportedOperationException(\"Iceberg runtime produced an unsupported changelog task; check version alignment\", e);\n}","preventionTips":["Pin the Iceberg runtime to versions producing only supported ChangelogScanTask subtypes","Re-run pipeline tests after any Iceberg upgrade","Centralize task-type checks in one guard utility"],"tags":["iceberg","cdc","serialization","version-compatibility"],"backgroundTag":"invalid-enum-value","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"}