{"record":{"id":"ed42e25bf41c03d7","repo":"apache/iceberg","slug":"cannot-wrap-catalog-that-does-not-produce-basetran","errorCode":null,"errorMessage":"Cannot wrap catalog that does not produce BaseTransaction","messagePattern":"Cannot wrap catalog that does not produce BaseTransaction","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java","lineNumber":548,"sourceCode":"      // metadata tables are loaded on the client side, return NoSuchTableException for now\n      throw new NoSuchTableException(\"Table does not exist: %s\", ident);\n    }\n\n    throw new IllegalStateException(\"Cannot wrap catalog that does not produce BaseTable\");\n  }\n\n  public static LoadTableResponse updateTable(\n      Catalog catalog, TableIdentifier ident, UpdateTableRequest request) {\n    TableMetadata finalMetadata;\n    if (isCreate(request)) {\n      // this is a hacky way to get TableOperations for an uncommitted table\n      Transaction transaction =\n          catalog.buildTable(ident, EMPTY_SCHEMA).createOrReplaceTransaction();\n      if (transaction instanceof BaseTransaction) {\n        BaseTransaction baseTransaction = (BaseTransaction) transaction;\n        finalMetadata = create(baseTransaction.underlyingOps(), request);\n      } else {\n        throw new IllegalStateException(\n            \"Cannot wrap catalog that does not produce BaseTransaction\");\n      }\n\n    } else {\n      Table table = catalog.loadTable(ident);\n      if (table instanceof BaseTable) {\n        TableOperations ops = ((BaseTable) table).operations();\n        finalMetadata = commit(ops, request);\n      } else {\n        throw new IllegalStateException(\"Cannot wrap catalog that does not produce BaseTable\");\n      }\n    }\n\n    return LoadTableResponse.builder().withTableMetadata(finalMetadata).build();\n  }\n\n  public static void renameTable(Catalog catalog, RenameTableRequest request) {\n    catalog.renameTable(request.source(), request.destination());","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java#L530-L566","documentation":"For a create-or-replace request, updateTable builds a Transaction via catalog.buildTable(ident, EMPTY_SCHEMA).createOrReplaceTransaction() and needs a BaseTransaction to access underlyingOps() and apply request requirements/updates; a Transaction of another implementation cannot be wrapped, so the handler throws IllegalStateException.","triggerScenarios":"POST /v1/{prefix}/namespaces/{ns}/tables with an UpdateTableRequest that is a create/replace, against a catalog whose createOrReplaceTransaction returns a non-BaseTransaction Transaction.","commonSituations":"Custom Catalog implementations behind the REST adapter; catalogs that return decorated transactions; mismatched Iceberg versions where transaction types differ.","solutions":["Use a catalog implementation that returns BaseTransaction from createOrReplaceTransaction (e.g. extend BaseMetastoreCatalog)","Avoid wrapping/decorating Transaction objects before the handler consumes them","Align server-side Iceberg dependency versions so transaction classes are the core ones"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"Transaction tx = catalog.buildTable(ident, schema).createOrReplaceTransaction();\nif (!(tx instanceof BaseTransaction)) {\n  throw new IllegalStateException(\"Catalog must produce BaseTransaction: \" + tx.getClass());\n}","typeGuard":"function isBaseTransaction(t) { return t instanceof org.apache.iceberg.BaseTransaction; }","tryCatchPattern":"try {\n  resp = CatalogHandlers.updateTable(catalog, ident, request);\n} catch (IllegalStateException e) {\n  // swap to a catalog that produces BaseTransaction\n}","preventionTips":["Test create/replace flows with the real catalog before deploying the REST adapter","Do not decorate Transaction instances in catalog implementations","Align Iceberg core versions across catalog modules"],"tags":["rest-catalog","illegal-state","transaction","create-table"],"backgroundTag":"internal-invariant-violation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}