{"record":{"id":"4b9e6dd578264af8","repo":"apache/iceberg","slug":"viewalreadyexistsexception-ident-4b9e6d","errorCode":null,"errorMessage":"ViewAlreadyExistsException(ident)","messagePattern":"ViewAlreadyExistsException\\(ident\\)","errorType":"exception","errorClass":"ViewAlreadyExistsException","httpStatus":409,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java","lineNumber":658,"sourceCode":"\n  @Override\n  public void renameView(Identifier fromIdentifier, Identifier toIdentifier)\n      throws NoSuchViewException, ViewAlreadyExistsException {\n    checkTableNotExists(toIdentifier);\n\n    if (null != asViewCatalog && asViewCatalog.viewExists(fromIdentifier)) {\n      asViewCatalog.renameView(fromIdentifier, toIdentifier);\n    } else if (isViewCatalog()) {\n      getSessionCatalog().renameView(fromIdentifier, toIdentifier);\n    } else {\n      throw new UnsupportedOperationException(\n          \"Renaming a view is not supported by catalog: \" + catalogName);\n    }\n  }\n\n  private void checkTableNotExists(Identifier ident) throws ViewAlreadyExistsException {\n    if (tableExists(ident)) {\n      throw new ViewAlreadyExistsException(ident);\n    }\n  }\n\n  private void checkViewNotExists(Identifier ident) throws TableAlreadyExistsException {\n    if (viewExists(ident)) {\n      throw new TableAlreadyExistsException(ident);\n    }\n  }\n}\n","sourceCodeStart":640,"sourceCodeEnd":668,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java#L640-L668","documentation":"Before creating or renaming a view, SparkSessionCatalog calls checkTableNotExists, which throws ViewAlreadyExistsException if a table already exists at the identifier. This guard prevents view DDL from silently colliding with an existing table of the same name. It reflects Iceberg's strict namespace separation: a name can only be one thing.","triggerScenarios":"CREATE VIEW db.v (or renameView landing on db.v) when a table named db.v already exists in the catalog.","commonSituations":"Name collisions between legacy tables and new views; re-running idempotent DDL scripts that previously created a table with the same name; migration scripts assuming views and tables share separate namespaces.","solutions":["Drop the existing table at that identifier before creating the view","Use a different identifier for the view","Check catalog.tableExists(ident) first and branch your DDL logic","Use CREATE OR REPLACE VIEW if you intend to replace (note this replaces views, not tables)"],"exampleFix":"// before\nspark.sql(\"CREATE VIEW db.v AS SELECT 1\"); // ViewAlreadyExistsException if db.v is a table\n// after\nif (!catalog.tableExists(Identifier.of(new String[]{\"db\"}, \"v\"))) {\n  spark.sql(\"CREATE VIEW db.v AS SELECT 1\");\n}","handlingStrategy":"validation","validationCode":"if (catalog.tableExists(ident)) {\n  throw new IllegalStateException(\"Table \" + ident + \" blocks view creation at this name\");\n}","typeGuard":"boolean nameFreeForView = !catalog.tableExists(ident);","tryCatchPattern":"try {\n  catalog.createView(ident, sql, schema);\n} catch (org.apache.iceberg.exceptions.ViewAlreadyExistsException e) {\n  // drop the conflicting table or choose a new name\n}","preventionTips":["Check tableExists before creating views with the same name","Use distinct naming conventions for tables vs views","Make DDL scripts idempotent: drop-if-exists or conditional create","Audit legacy table names before introducing views"],"tags":["spark","catalog","views","name-collision"],"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-14T21:17:11.552Z"}