{"record":{"id":"48ed2e6203c29c3a","repo":"apache/iceberg","slug":"operation-updatespec-is-not-supported-after-the-ta","errorCode":null,"errorMessage":"Operation updateSpec is not supported after the table is serialized","messagePattern":"Operation updateSpec is not supported after the table is serialized","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SerializableTable.java","lineNumber":357,"sourceCode":"\n  @Override\n  public Iterable<Snapshot> snapshots() {\n    return lazyTable().snapshots();\n  }\n\n  @Override\n  public List<HistoryEntry> history() {\n    return lazyTable().history();\n  }\n\n  @Override\n  public UpdateSchema updateSchema() {\n    throw new UnsupportedOperationException(errorMsg(\"updateSchema\"));\n  }\n\n  @Override\n  public UpdatePartitionSpec updateSpec() {\n    throw new UnsupportedOperationException(errorMsg(\"updateSpec\"));\n  }\n\n  @Override\n  public UpdateProperties updateProperties() {\n    throw new UnsupportedOperationException(errorMsg(\"updateProperties\"));\n  }\n\n  @Override\n  public ReplaceSortOrder replaceSortOrder() {\n    throw new UnsupportedOperationException(errorMsg(\"replaceSortOrder\"));\n  }\n\n  @Override\n  public UpdateLocation updateLocation() {\n    throw new UnsupportedOperationException(errorMsg(\"updateLocation\"));\n  }\n\n  @Override","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SerializableTable.java#L339-L375","documentation":"SerializableTable guard: the table was serialized to a remote engine and this handle carries only read state, so updateSpec() (partition-spec evolution) is refused. Mutating operations must go through the original Table obtained from the catalog in the driver, not the deserialized copy.","triggerScenarios":"Calling updateSpec() on a SerializableTable instance, e.g., in distributed task code or after wrapping with SerializableTable.of().","commonSituations":"Job code that evolves partitioning mid-pipeline using a table handle that was serialized for executors.","solutions":["Perform the partition evolution on the driver with a live catalog table","Pass a reference to the Catalog and identifier instead of the serialized table","Restrict SerializableTable usage to read paths (scans, reads)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (table instanceof SerializableTable) { throw new UnsupportedOperationException(\"Spec updates require a live catalog table\"); }","typeGuard":"boolean canWrite = !(table instanceof SerializableTable);","tryCatchPattern":"try { table.updateSpec().commit(); } catch (UnsupportedOperationException e) { catalog.loadTable(id).updateSpec().commit(); }","preventionTips":["Keep partition evolution on the driver","Never serialize tables intended for write operations"],"tags":["iceberg","serialization","read-only"],"backgroundTag":"operation-not-supported","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"}