{"record":{"id":"1426337ee821ce5d","repo":"apache/iceberg","slug":"viewalreadyexistsexception-ident","errorCode":null,"errorMessage":"ViewAlreadyExistsException(ident)","messagePattern":"ViewAlreadyExistsException\\(ident\\)","errorType":"exception","errorClass":"ViewAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java","lineNumber":640,"sourceCode":"                .putAll(Spark3Util.rebuildCreateProperties(properties))\n                .put(SparkView.QUERY_COLUMN_NAMES, COMMA_JOINER.join(queryColumnNames))\n                .buildKeepingLast();\n\n        org.apache.iceberg.view.View view =\n            asViewCatalog\n                .buildView(buildIdentifier(ident))\n                .withDefaultCatalog(currentCatalog)\n                .withDefaultNamespace(Namespace.of(currentNamespace))\n                .withQuery(\"spark\", sql)\n                .withSchema(icebergSchema)\n                .withLocation(properties.get(\"location\"))\n                .withProperties(props)\n                .create();\n        return new SparkView(catalogName, view);\n      } catch (org.apache.iceberg.exceptions.NoSuchNamespaceException e) {\n        throw new NoSuchNamespaceException(currentNamespace);\n      } catch (AlreadyExistsException e) {\n        throw new ViewAlreadyExistsException(ident);\n      }\n    }\n\n    throw new UnsupportedOperationException(\n        \"Creating a view is not supported by catalog: \" + catalogName);\n  }\n\n  @Override\n  public View replaceView(\n      Identifier ident,\n      String sql,\n      String currentCatalog,\n      String[] currentNamespace,\n      StructType schema,\n      String[] queryColumnNames,\n      String[] columnAliases,\n      String[] columnComments,\n      Map<String, String> properties)","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java#L622-L658","documentation":"When createView's underlying ViewBuilder .create() fails with Iceberg's AlreadyExistsException, it is converted to Spark's ViewAlreadyExistsException for the identifier. The view with that exact name already exists in the catalog and plain CREATE VIEW refuses to overwrite it.","triggerScenarios":"CREATE VIEW catalog.db.name executed when a view (and in most catalogs also a table) with that identifier already exists; concurrent pipelines both attempting CREATE VIEW for the same name.","commonSituations":"Re-running non-idempotent migration/ETL scripts that create views; two jobs racing to create the same view; confusion between tables and views sharing the same name in the catalog; forgetting IF NOT EXISTS in DDL.","solutions":["Use CREATE VIEW IF NOT EXISTS (or CREATE OR REPLACE VIEW) to make the statement idempotent","Drop the existing view first if replacement is intended: DROP VIEW catalog.db.name then recreate","Pick a different view name if the existing object is intentional","Handle ViewAlreadyExistsException in code and treat it as success when creation is best-effort"],"exampleFix":"// before\nCREATE VIEW prod.analytics.daily_summary AS SELECT ...;\n// after\nCREATE VIEW IF NOT EXISTS prod.analytics.daily_summary AS SELECT ...;\n// or: CREATE OR REPLACE VIEW prod.analytics.daily_summary AS SELECT ...;","handlingStrategy":"validation","validationCode":"boolean exists = spark.sql(\"SHOW VIEWS IN \" + db).collectAsList().stream()\n    .anyMatch(r -> r.getString(0).equalsIgnoreCase(name));\n// choose IF NOT EXISTS vs CREATE OR REPLACE based on `exists` and intent","typeGuard":null,"tryCatchPattern":"try {\n  spark.sql(\"CREATE VIEW \" + ident + \" AS SELECT ...;\");\n} catch (org.apache.spark.sql.catalyst.analysis.ViewAlreadyExistsException e) {\n  spark.sql(\"CREATE OR REPLACE VIEW \" + ident + \" AS SELECT ...;\");\n}","preventionTips":["Use CREATE VIEW IF NOT EXISTS or CREATE OR REPLACE VIEW in re-runnable scripts","Version your view DDL so repeated deployments are idempotent","Avoid duplicate CREATE VIEW in concurrently running jobs (serialize or lock)","Remember tables and views are separate catalogs entries — check both with SHOW TABLES/SHOW VIEWS"],"tags":["spark","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"}