{"record":{"id":"6e0f6170b5ba85b9","repo":"apache/iceberg","slug":"unexpected-action-type-for-delta-lake-s","errorCode":null,"errorMessage":"Unexpected action type for Delta Lake: %s","messagePattern":"Unexpected action type for Delta Lake: (.+?)","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"delta-lake/src/main/java/org/apache/iceberg/delta/BaseSnapshotDeltaLakeTableAction.java","lineNumber":356,"sourceCode":"  private DataFile buildDataFileFromAction(Action action, Table table) {\n    PartitionSpec spec = table.spec();\n    String path;\n    long fileSize;\n    Long nullableFileSize;\n    Map<String, String> partitionValues;\n\n    if (action instanceof AddFile) {\n      AddFile addFile = (AddFile) action;\n      path = addFile.getPath();\n      nullableFileSize = addFile.getSize();\n      partitionValues = addFile.getPartitionValues();\n    } else if (action instanceof RemoveFile) {\n      RemoveFile removeFile = (RemoveFile) action;\n      path = removeFile.getPath();\n      nullableFileSize = removeFile.getSize().orElse(null);\n      partitionValues = removeFile.getPartitionValues();\n    } else {\n      throw new ValidationException(\n          \"Unexpected action type for Delta Lake: %s\", action.getClass().getSimpleName());\n    }\n\n    String fullFilePath = getFullFilePath(path, deltaLog.getPath().toString());\n    // For unpartitioned table, the partitionValues should be an empty map rather than null\n    Preconditions.checkArgument(\n        partitionValues != null,\n        String.format(\"File %s does not specify a partitionValues\", fullFilePath));\n\n    FileFormat format = determineFileFormatFromPath(fullFilePath);\n    InputFile file = deltaLakeFileIO.newInputFile(fullFilePath);\n    if (!file.exists()) {\n      throw new NotFoundException(\n          \"File %s is referenced in the logs of Delta Lake table at %s, but cannot be found in the storage\",\n          fullFilePath, deltaTableLocation);\n    }\n\n    // If the file size is not specified, the size should be read from the file","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/delta-lake/src/main/java/org/apache/iceberg/delta/BaseSnapshotDeltaLakeTableAction.java#L338-L374","documentation":"Thrown by BaseSnapshotDeltaLakeTableAction when converting Delta Lake log actions into Iceberg DataFiles and an action object is neither an AddFile nor a RemoveFile. The Delta standalone log reader surfaced an action type this migration/snapshot procedure does not map, so conversion fails fast instead of producing a corrupt DataFile.","triggerScenarios":"Calling SnapshotDeltaLakeTable/SnapshotDeltaLakeTableAction on a Delta table whose transaction log contains an action type other than AddFile or RemoveFile reaching buildDataFileFromAction (e.g. newly introduced Delta log entries, metadata/commit actions passed in by a newer delta-standalone reader, or CDC entries).","commonSituations":"Migrating Delta tables written by newer Delta Lake protocol versions than the delta-standalone library supports; plugin or fork code that feeds custom actions into dataFile(); protocol upgrade on the Delta table after an Iceberg snapshot job was pinned to an older delta-standalone version.","solutions":["Upgrade org.apache.iceberg:iceberg-delta-lake and the delta-standalone dependency to versions matching the Delta writer version of the table (check _delta_log protocol minWriterVersion/minReaderVersion).","Inspect the table's _delta_log to identify which action types are present; filter or pre-process unsupported actions before snapshotting.","If a legitimate action type is missing from the mapping, patch BaseSnapshotDeltaLakeTableAction.buildDataFileFromAction to handle it.","As a workaround, rewrite/compact the Delta table with a tool version that emits only AddFile/RemoveFile actions, then rerun the snapshot."],"exampleFix":"// before: unhandled action falls through\n} else {\n  throw new ValidationException(\"Unexpected action type for Delta Lake: %s\", action.getClass().getSimpleName());\n}\n// after: upgrade delta-standalone so AddCDCFile etc. are mapped, e.g.\n} else if (action instanceof io.delta.standalone.actions.AddCDCFile) {\n  // map change-data-capture file or skip it intentionally\n}","handlingStrategy":"validation","validationCode":"if (!(action instanceof io.delta.standalone.actions.AddFile) && !(action instanceof io.delta.standalone.actions.RemoveFile)) {\n  throw new IllegalStateException(\"Unsupported Delta action: \" + action.getClass().getName());\n}","typeGuard":"boolean isSupported(Action a) {\n  return a instanceof AddFile || a instanceof RemoveFile;\n}","tryCatchPattern":null,"preventionTips":["Pin delta-standalone version to match the table's Delta protocol writer version.","Before migrating, scan _delta_log for unexpected action types.","Keep iceberg-delta-lake and delta-standalone upgrades in sync."],"tags":["delta-lake","migration","validation"],"backgroundTag":"invalid-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"}