{"record":{"id":"264e53f0585e21c2","repo":"apache/iceberg","slug":"cannot-call-commit-on-temporary-table-operations-264e53","errorCode":null,"errorMessage":"Cannot call commit on temporary table operations","messagePattern":"Cannot call commit on temporary table operations","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/RESTTableOperations.java","lineNumber":349,"sourceCode":"  }\n\n  @Override\n  public TableOperations temp(TableMetadata uncommittedMetadata) {\n    return new TableOperations() {\n      @Override\n      public TableMetadata current() {\n        return uncommittedMetadata;\n      }\n\n      @Override\n      public TableMetadata refresh() {\n        throw new UnsupportedOperationException(\n            \"Cannot call refresh on temporary table operations\");\n      }\n\n      @Override\n      public void commit(TableMetadata base, TableMetadata metadata) {\n        throw new UnsupportedOperationException(\"Cannot call commit on temporary table operations\");\n      }\n\n      @Override\n      public String metadataFileLocation(String fileName) {\n        return RESTTableOperations.metadataFileLocation(uncommittedMetadata, fileName);\n      }\n\n      @Override\n      public LocationProvider locationProvider() {\n        return LocationProviders.locationsFor(\n            uncommittedMetadata.location(), uncommittedMetadata.properties());\n      }\n\n      @Override\n      public FileIO io() {\n        return RESTTableOperations.this.io();\n      }\n","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/RESTTableOperations.java#L331-L367","documentation":"An UnsupportedOperationException thrown by the temporary TableOperations wrapper's commit(base, metadata). The temporary operations object only holds uncommitted metadata for a create/replace in progress; the real commit goes through the REST commit path, so a direct commit() on the temp wrapper is forbidden by design.","triggerScenarios":"Calling table.operations().commit(base, metadata) — or invoking APIs that route through TableOperations.commit — on the temporary operations used during a create/replace transaction in the REST catalog.","commonSituations":"Generic write pipelines that call operations().commit unconditionally, including on in-transaction table objects; custom append/overwrite helpers operating on a temp table snapshot; code written for real TableOperations reused against transactional temporary ones.","solutions":["Complete the transaction via the Builder/Transaction API (commitTransaction / Transaction.commit) instead of calling operations().commit directly.","Only call operations().commit on Table objects loaded from the catalog, never on the temporary in-transaction operations.","Catch UnsupportedOperationException in shared write helpers and route to the transactional path when detected.","Refactor helpers to accept a Transaction or SnapshotProducer rather than raw TableOperations."],"exampleFix":"// before\ntable.operations().commit(table.operations().current(), newMetadata); // temp ops\n// after\nTransaction tx = table.newTransaction();\n/* apply changes */\ntx.commitTransaction();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"boolean supportsCommit(TableOperations ops) { try { ops.commit(ops.current(), ops.current()); return true; } catch (UnsupportedOperationException e) { return false; } } // better: only commit via catalog-loaded TableOperations","tryCatchPattern":"try { ops.commit(base, metadata); } catch (UnsupportedOperationException e) { /* temporary operations: route through Transaction/Builder API */ }","preventionTips":["Apply changes via Transaction or Builder APIs, never operations().commit on temp ops","Only call operations().commit on tables loaded directly from the catalog","Design write helpers around Transaction/SnapshotProducer instead of raw TableOperations","Detect temporary operations early (refresh() throwing) and switch to the transactional path"],"tags":["rest","table-operations","unsupported-operation","commit"],"backgroundTag":"method-not-implemented","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"}