{"record":{"id":"e39523ae73ea2919","repo":"apache/iceberg","slug":"unsupported-task-type","errorCode":null,"errorMessage":"Unsupported task type: ","messagePattern":"Unsupported task type: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/ScanTaskParser.java","lineNumber":102,"sourceCode":"      generator.writeStringField(TASK_TYPE, TaskType.DATA_TASK.typeName());\n      DataTaskParser.toJson((StaticDataTask) fileScanTask, generator);\n    } else if (fileScanTask instanceof BaseFilesTable.ManifestReadTask) {\n      generator.writeStringField(TASK_TYPE, TaskType.FILES_TABLE_TASK.typeName());\n      FilesTableTaskParser.toJson((BaseFilesTable.ManifestReadTask) fileScanTask, generator);\n    } else if (fileScanTask instanceof AllManifestsTable.ManifestListReadTask) {\n      generator.writeStringField(TASK_TYPE, TaskType.ALL_MANIFESTS_TABLE_TASK.typeName());\n      AllManifestsTableTaskParser.toJson(\n          (AllManifestsTable.ManifestListReadTask) fileScanTask, generator);\n    } else if (fileScanTask instanceof BaseEntriesTable.ManifestReadTask) {\n      generator.writeStringField(TASK_TYPE, TaskType.MANIFEST_ENTRIES_TABLE_TASK.typeName());\n      ManifestEntriesTableTaskParser.toJson(\n          (BaseEntriesTable.ManifestReadTask) fileScanTask, generator);\n    } else if (fileScanTask instanceof BaseFileScanTask\n        || fileScanTask instanceof BaseFileScanTask.SplitScanTask) {\n      generator.writeStringField(TASK_TYPE, TaskType.FILE_SCAN_TASK.typeName());\n      FileScanTaskParser.toJson(fileScanTask, generator);\n    } else {\n      throw new UnsupportedOperationException(\n          \"Unsupported task type: \" + fileScanTask.getClass().getCanonicalName());\n    }\n\n    generator.writeEndObject();\n  }\n\n  private static FileScanTask fromJson(JsonNode jsonNode, boolean caseSensitive) {\n    TaskType taskType = TaskType.FILE_SCAN_TASK;\n    String taskTypeStr = JsonUtil.getStringOrNull(TASK_TYPE, jsonNode);\n    if (null != taskTypeStr) {\n      taskType = TaskType.fromTypeName(taskTypeStr);\n    }\n\n    switch (taskType) {\n      case FILE_SCAN_TASK:\n        return FileScanTaskParser.fromJson(jsonNode, caseSensitive);\n      case DATA_TASK:\n        return DataTaskParser.fromJson(jsonNode);","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/ScanTaskParser.java#L84-L120","documentation":"ScanTaskParser.toJson(FileScanTask, JsonGenerator) only knows how to serialize a fixed set of FileScanTask implementations: StaticDataTask, BaseFilesTable.ManifestReadTask, AllManifestsTable.ManifestListReadTask, BaseEntriesTable.ManifestReadTask, and BaseFileScanTask (including SplitScanTask). Any other FileScanTask implementation hits the else branch and throws this UnsupportedOperationException naming the class. It exists because serialization is type-dispatched and custom/unknown implementations have no JSON representation.","triggerScenarios":"Calling ScanTaskParser.toJson(task) with a custom FileScanTask implementation, a subclass that does not extend BaseFileScanTask, or a task type introduced in a newer Iceberg release that this parser does not recognize.","commonSituations":"Custom scan task implementations in downstream projects passed to the parser; mixed-version clusters where a task class from a newer Iceberg reaches an older serializer; wrapping/decorating FileScanTask objects and then serializing the wrapper.","solutions":["Serialize the underlying BaseFileScanTask (e.g. task.asFileScanTask() or the wrapped delegate) instead of the custom wrapper","Extend BaseFileScanTask or BaseFileScanTask.SplitScanTask so the instanceof checks recognize your implementation","Upgrade Iceberg so the parser recognizes the task class, or add explicit serialization handling in your own code"],"exampleFix":"// before\nScanTaskParser.toJson(new MyCustomFileScanTask(delegate));\n// after\nScanTaskParser.toJson(delegate); // serialize the BaseFileScanTask, not the wrapper","handlingStrategy":"type-guard","validationCode":"if (!(task instanceof StaticDataTask || task instanceof BaseFilesTable.ManifestReadTask || task instanceof AllManifestsTable.ManifestListReadTask || task instanceof BaseEntriesTable.ManifestReadTask || task instanceof BaseFileScanTask)) {\n  throw new IllegalArgumentException(\"Task type not serializable by ScanTaskParser: \" + task.getClass().getName());\n}","typeGuard":"static boolean isSerializableScanTask(FileScanTask t) {\n  return t instanceof StaticDataTask || t instanceof BaseFileScanTask || t instanceof BaseFileScanTask.SplitScanTask\n      || t instanceof BaseFilesTable.ManifestReadTask || t instanceof AllManifestsTable.ManifestListReadTask || t instanceof BaseEntriesTable.ManifestReadTask;\n}","tryCatchPattern":"try {\n  return ScanTaskParser.toJson(task);\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\"Cannot serialize custom scan task \" + task.getClass().getName() + \"; serialize its BaseFileScanTask delegate instead\", e);\n}","preventionTips":["Extend BaseFileScanTask or SplitScanTask for custom tasks so the parser recognizes them","Unwrap decorators/wrappers before serializing","Do not pass tasks from newer Iceberg versions into an older runtime's parser"],"tags":["json","serialization","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}