{"record":{"id":"29a3607005235d59","repo":"apache/iceberg","slug":"cannot-apply-unknown-table-change-change-29a360","errorCode":null,"errorMessage":"Cannot apply unknown table change: <change>","messagePattern":"Cannot apply unknown table change: <change>","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java","lineNumber":152,"sourceCode":"   * Applies a list of Spark table changes to an {@link UpdateProperties} operation.\n   *\n   * @param pendingUpdate an uncommitted UpdateProperties operation to configure\n   * @param changes a list of Spark table changes\n   * @return the UpdateProperties operation configured with the changes\n   */\n  public static UpdateProperties applyPropertyChanges(\n      UpdateProperties pendingUpdate, List<TableChange> changes) {\n    for (TableChange change : changes) {\n      if (change instanceof TableChange.SetProperty) {\n        TableChange.SetProperty set = (TableChange.SetProperty) change;\n        pendingUpdate.set(set.property(), set.value());\n\n      } else if (change instanceof TableChange.RemoveProperty) {\n        TableChange.RemoveProperty remove = (TableChange.RemoveProperty) change;\n        pendingUpdate.remove(remove.property());\n\n      } else {\n        throw new UnsupportedOperationException(\"Cannot apply unknown table change: \" + change);\n      }\n    }\n\n    return pendingUpdate;\n  }\n\n  /**\n   * Applies a list of Spark table changes to an {@link UpdateSchema} operation.\n   *\n   * @param pendingUpdate an uncommitted UpdateSchema operation to configure\n   * @param changes a list of Spark table changes\n   * @return the UpdateSchema operation configured with the changes\n   */\n  public static UpdateSchema applySchemaChanges(\n      UpdateSchema pendingUpdate, List<TableChange> changes) {\n    for (TableChange change : changes) {\n      if (change instanceof TableChange.AddColumn) {\n        apply(pendingUpdate, (TableChange.AddColumn) change);","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java#L134-L170","documentation":"Spark3Util.applyPropertyChanges applies Spark DDL table property changes to an Iceberg PendingUpdate. Any TableChange that is not SetProperty or RemoveProperty reaches this final else branch, and the library refuses to guess its intent, throwing UnsupportedOperationException with the change description.","triggerScenarios":"Calling Spark3Util.applyPropertyChanges with a TableChange instance other than TableChange.SetProperty or TableChange.RemoveProperty, e.g. a column-level change misrouted into the property path.","commonSituations":"Custom catalog/extension code building TableChange lists manually; framework versions where new TableChange subtypes were added upstream but this conversion path was not updated.","solutions":["Only pass property-type changes (SetProperty/RemoveProperty) to applyPropertyChanges; route column changes through applySchemaChanges","Add a case for the missing TableChange subtype before calling this method, handling it via pendingUpdate explicitly","Check the Iceberg/Spark version pairing — new TableChange types may need a newer Iceberg build"],"exampleFix":"// before\nSpark3Util.applyPropertyChanges(table, allChanges);\n// after\nList<TableChange> props = allChanges.stream()\n    .filter(c -> c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty)\n    .collect(Collectors.toList());\nSpark3Util.applyPropertyChanges(table, props);","handlingStrategy":"type-guard","validationCode":"boolean isPropertyChange(TableChange c) {\n  return c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty;\n}\n// filter list before calling\nchanges.stream().filter(this::isPropertyChange).collect(Collectors.toList());","typeGuard":"static boolean isPropertyChange(TableChange c) {\n  return c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty;\n}","tryCatchPattern":"try {\n  Spark3Util.applyPropertyChanges(table, changes);\n} catch (UnsupportedOperationException e) {\n  // log the unsupported change type and route it to a supported path\n}","preventionTips":["Partition the TableChange list by subtype before applying","Keep the changes-construction code adjacent to the apply code so subtypes stay visible","Pin and test Iceberg/Spark versions together"],"tags":["spark","unsupported-operation","table-change"],"backgroundTag":"unsupported-operation","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"}