{"record":{"id":"204b95e8ac389844","repo":"apache/iceberg","slug":"view-already-exists-s-204b95","errorCode":null,"errorMessage":"View already exists: %s","messagePattern":"View already exists: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":409,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/view/BaseMetastoreViewCatalog.java","lineNumber":184,"sourceCode":"\n    @Override\n    public View replace() {\n      return replace(newViewOps(identifier));\n    }\n\n    @Override\n    public View createOrReplace() {\n      ViewOperations ops = newViewOps(identifier);\n      if (null == ops.current()) {\n        return create(ops);\n      } else {\n        return replace(ops);\n      }\n    }\n\n    private View create(ViewOperations ops) {\n      if (null != ops.current()) {\n        throw new AlreadyExistsException(\"View already exists: %s\", identifier);\n      }\n\n      Preconditions.checkState(\n          !representations.isEmpty(), \"Cannot create view without specifying a query\");\n      Preconditions.checkState(null != schema, \"Cannot create view without specifying schema\");\n      Preconditions.checkState(\n          null != defaultNamespace, \"Cannot create view without specifying a default namespace\");\n\n      ViewVersion viewVersion =\n          ImmutableViewVersion.builder()\n              .versionId(1)\n              .schemaId(schema.schemaId())\n              .addAllRepresentations(representations)\n              .defaultNamespace(defaultNamespace)\n              .defaultCatalog(defaultCatalog)\n              .timestampMillis(System.currentTimeMillis())\n              .putAllSummary(EnvironmentContext.get())\n              .build();","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/view/BaseMetastoreViewCatalog.java#L166-L202","documentation":"BaseViewBuilder.create commits a new view but first checks ViewOperations.current(). If view metadata already exists, it throws AlreadyExistsException because create() must not overwrite an existing view (use createOrReplace or replace for that).","triggerScenarios":"Calling catalog.buildView(ident)...create() (or createOrReplace where the replace branch routes here) when a view with that identifier already exists in the metastore.","commonSituations":"Race between two jobs creating the same view name; rerunning idempotent setup scripts without createOrReplace; leftover view from a previous run.","solutions":["Use createOrReplace(...) instead of create(...) when overwriting is intended","Drop the existing view first (catalog.dropView(identifier))","Use catalog.viewExists(identifier) as an existence guard before create"],"exampleFix":"// before\ncatalog.buildView(ident).withQuery(\"sql\", \"select 1\").create();\n// after\ncatalog.buildView(ident).withQuery(\"sql\", \"select 1\").createOrReplace();","handlingStrategy":"try-catch","validationCode":"if (catalog.viewExists(identifier) && !allowOverwrite) { throw new IllegalStateException(\"View \" + identifier + \" already exists\"); }","typeGuard":null,"tryCatchPattern":"try { return builder.create(); } catch (AlreadyExistsException e) { return catalog.loadView(identifier); /* idempotent create */ }","preventionTips":["Prefer createOrReplace for repeatable DDL scripts","Check viewExists before create in setup code","Serialize view DDL through one job/lock"],"tags":["catalog","view","already-exists"],"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"}