{"record":{"id":"926948c1f22d1108","repo":"apache/iceberg","slug":"view-with-same-name-already-exists-s-926948","errorCode":null,"errorMessage":"View with same name already exists: %s","messagePattern":"View with same name already exists: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":409,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java","lineNumber":1068,"sourceCode":"                  tableConf,\n                  response.credentials(),\n                  response.remoteSigningConfig()),\n              RESTTableOperations.UpdateType.CREATE,\n              createChanges(meta),\n              meta,\n              endpoints);\n\n      trackFileIO(ops);\n\n      return Transactions.createTableTransaction(\n          fullName, ops, meta, metricsReporter(paths.metrics(ident), tableClient));\n    }\n\n    @Override\n    public Transaction replaceTransaction() {\n      Endpoint.check(endpoints, Endpoint.V1_UPDATE_TABLE);\n      if (viewExists(context, ident)) {\n        throw new AlreadyExistsException(\"View with same name already exists: %s\", ident);\n      }\n\n      LoadTableResponse response = loadInternal(context, ident, snapshotMode, Map.of(), h -> {});\n\n      String fullName = fullTableName(ident);\n\n      Map<String, String> tableConf = response.config();\n      AuthSession contextualSession = authManager.contextualSession(context, catalogAuth);\n      AuthSession tableSession = authManager.tableSession(ident, tableConf, contextualSession);\n      TableMetadata base = response.tableMetadata();\n\n      propertiesBuilder.putAll(tableOverrideProperties());\n      Map<String, String> tableProperties = propertiesBuilder.buildKeepingLast();\n      TableMetadata replacement =\n          base.buildReplacement(\n              schema,\n              spec != null ? spec : PartitionSpec.unpartitioned(),\n              writeOrder != null ? writeOrder : SortOrder.unsorted(),","sourceCodeStart":1050,"sourceCodeEnd":1086,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java#L1050-L1086","documentation":"An AlreadyExistsException thrown by the view Builder's replaceTransaction() in RESTSessionCatalog when a view with the same identifier already exists on the server. replaceTransaction is meant to atomically replace an existing view; if the name resolves to a view, the operation conflicts and is rejected before sending the replacement request.","triggerScenarios":"Calling viewBuilder(...).replaceTransaction() (or SQL CREATE OR REPLACE via this path) when viewExists(context, ident) is true — i.e., the target name is an existing view.","commonSituations":"Concurrent CREATE OR REPLACE VIEW statements racing on the same view name; a script that assumes the view does not exist; namespace confusion where the view already exists under a resolved default namespace.","solutions":["Check catalog.viewExists(identifier) first and decide whether replace, create, or drop is intended.","Catch org.apache.iceberg.exceptions.AlreadyExistsException and handle the conflict explicitly.","Use dropView then createView if unconditional replacement semantics are desired (non-atomically).","Verify the identifier/namespace resolution — the existing view may be under a different resolved namespace than expected."],"exampleFix":"// before\nviewBuilder(ident).replaceTransaction().commitTransaction();\n// after\nif (!catalog.viewExists(ident)) { /* create */ } else { catalog.loadView(ident).replace().commit(); }","handlingStrategy":"validation","validationCode":"if (catalog.viewExists(identifier)) { /* handle existing view: replace() vs skip vs drop */ }","typeGuard":null,"tryCatchPattern":"try { builder.replaceTransaction().commitTransaction(); } catch (AlreadyExistsException e) { /* view already exists: resolve conflict */ }","preventionTips":["Check viewExists before replaceTransaction","Standardize on explicit create-or-replace logic with conflict handling","Catch AlreadyExistsException around concurrent replace flows","Confirm namespace resolution matches where the view actually lives"],"tags":["rest","view","already-exists","conflict"],"backgroundTag":"file-already-exists","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"}