{"record":{"id":"04e53d06d2324910","repo":"apache/iceberg","slug":"cannot-rename-s-to-s-view-already-exists-04e53d","errorCode":null,"errorMessage":"Cannot rename %s to %s. View already exists","messagePattern":"Cannot rename (.+?) to (.+?)\\. View already exists","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":409,"severity":"error","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java","lineNumber":519,"sourceCode":"    } catch (HttpClientException ex) {\n      // Intentionally catch all nessie-client-exceptions here and not just the \"timeout\" variant\n      // to catch all kinds of network errors (e.g. connection reset). Network code implementation\n      // details and all kinds of network devices can induce unexpected behavior. So better be\n      // safe than sorry.\n      throw new CommitStateUnknownException(ex);\n    }\n    // Intentionally just \"throw through\" Nessie's HttpClientException here and do not \"special\n    // case\"\n    // just the \"timeout\" variant to propagate all kinds of network errors (e.g. connection reset).\n    // Network code implementation details and all kinds of network devices can induce unexpected\n    // behavior. So better be safe than sorry.\n  }\n\n  private static void validateToContentForRename(\n      TableIdentifier from, TableIdentifier to, IcebergContent existingToContent) {\n    if (existingToContent != null) {\n      if (existingToContent.getType() == Content.Type.ICEBERG_VIEW) {\n        throw new AlreadyExistsException(\"Cannot rename %s to %s. View already exists\", from, to);\n      } else if (existingToContent.getType() == Content.Type.ICEBERG_TABLE) {\n        throw new AlreadyExistsException(\"Cannot rename %s to %s. Table already exists\", from, to);\n      } else {\n        throw new AlreadyExistsException(\n            \"Cannot rename %s to %s. Another content of type %s with same name already exists\",\n            from, to, existingToContent.getType());\n      }\n    }\n  }\n\n  private static void validateFromContentForRename(\n      TableIdentifier from, Content.Type type, IcebergContent existingFromContent) {\n    if (existingFromContent == null) {\n      if (type == Content.Type.ICEBERG_VIEW) {\n        throw new NoSuchViewException(\"View does not exist: %s\", from);\n      } else if (type == Content.Type.ICEBERG_TABLE) {\n        throw new NoSuchTableException(\"Table does not exist: %s\", from);\n      } else {","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java#L501-L537","documentation":"validateToContentForRename refuses a rename when the destination identifier already holds content of type ICEBERG_VIEW. renameTable/renameView first fetch the destination's existing content and throw Iceberg's AlreadyExistsException to prevent silently overwriting a view.","triggerScenarios":"catalog.renameTable(from, to) where 'to' names an existing view, or catalog.renameView(from, to) where 'to' names an existing view — fetchContent(to) returns a non-null IcebergContent with type ICEBERG_VIEW.","commonSituations":"Naming collision between table and view namespaces in mixed Spark/Iceberg setups; recreating a pipeline that previously created a view at the target name; case-sensitivity confusion producing seemingly 'new' names that actually match existing views.","solutions":["Drop or rename the existing view at the destination first, then rerun the rename.","Choose a different destination identifier that is not in use (check with tableExists/namespace listing).","If the view should be replaced intentionally, drop it explicitly rather than relying on rename to overwrite.","Check whether identifier case sensitivity (support-case-sensitive-paths / quoting) makes you collide with an unexpected existing view."],"exampleFix":"// before\ncatalog.renameTable(TableIdentifier.of(\"ns\",\"events\"), TableIdentifier.of(\"ns\",\"events_view\")); // view exists there\n// after\nif (catalog.tableExists(TableIdentifier.of(\"ns\",\"events_view\")) || viewExists(catalog, \"ns.events_view\")) {\n  catalog.dropTable(TableIdentifier.of(\"ns\",\"events_view\"));\n}\ncatalog.renameTable(TableIdentifier.of(\"ns\",\"events\"), TableIdentifier.of(\"ns\",\"events_view\"));","handlingStrategy":"validation","validationCode":"// listNamespaces + table/view checks before renaming\nboolean destFree = !catalog.tableExists(to) && !viewExists(catalog, to);\nif (!destFree) { throw new ValidationException(\"destination in use: \" + to); }","typeGuard":null,"tryCatchPattern":"try {\n  catalog.renameTable(from, to);\n} catch (AlreadyExistsException e) {\n  LOGGER.error(\"destination {} already exists ({})\", to, e.getMessage());\n  // pick another destination or drop explicitly\n}","preventionTips":["Check the destination for any existing content before every rename.","Make rename migrations idempotent: skip if the destination already equals the expected state.","Watch out for identifier case sensitivity creating hidden collisions.","Keep views and tables in distinct namespaces where tooling permits."],"tags":["nessie","catalog","rename","already-exists","view"],"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"}