{"record":{"id":"fa1af21ac5d5ac33","repo":"apache/iceberg","slug":"view-already-exists-s-fa1af2","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/BaseViewOperations.java","lineNumber":115,"sourceCode":"      currentMetadataLocation = null;\n      version = -1;\n      throw e;\n    }\n\n    return current();\n  }\n\n  @Override\n  @SuppressWarnings(\"ImmutablesReferenceEquality\")\n  public void commit(ViewMetadata base, ViewMetadata metadata) {\n    // if the metadata is already out of date, reject it\n    if (base != current()) {\n      if (base != null) {\n        throw new CommitFailedException(\"Cannot commit: stale view metadata\");\n      } else {\n        // when current is non-null, the view exists. but when base is null, the commit is trying\n        // to create the view\n        throw new AlreadyExistsException(\"View already exists: %s\", viewName());\n      }\n    }\n\n    // if the metadata is not changed, return early\n    if (base == metadata) {\n      LOG.info(\"Nothing to commit.\");\n      return;\n    }\n\n    long start = System.currentTimeMillis();\n    doCommit(base, metadata);\n    requestRefresh();\n\n    LOG.info(\n        \"Successfully committed to view {} in {} ms\",\n        viewName(),\n        System.currentTimeMillis() - start);\n  }","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/view/BaseViewOperations.java#L97-L133","documentation":"When committing with a null base (i.e., attempting view creation), BaseViewOperations.commit checks whether the view already exists (current() != null). If so, the creation races with an existing view and throws AlreadyExistsException instead of silently overwriting.","triggerScenarios":"ops.commit(null, metadata) to create a view when current() is non-null — another client created the view first, or the caller mistakenly passed null base for an existing view.","commonSituations":"Concurrent CREATE VIEW statements targeting the same name; retry logic that re-commits with null base after the first commit actually succeeded; direct use of ViewOperations by custom catalogs.","solutions":["Check viewExists/load the view before creating; use CREATE OR REPLACE if overwrite is intended","Handle AlreadyExistsException and fall back to an update path","Retry with a fresh null-base creation only after confirming the view is absent"],"exampleFix":"// before\nops.commit(null, metadata); // create\n// after\nif (((BaseViewOperations) ops).current() == null) {\n  ops.commit(null, metadata);\n} else {\n  ops.commit(((BaseViewOperations) ops).current(), metadata); // replace\n}","handlingStrategy":"validation","validationCode":"boolean viewExists = ((BaseViewOperations) ops).current() != null; if (base == null && viewExists) { /* use replace, not create */ }","typeGuard":null,"tryCatchPattern":"try { ops.commit(null, metadata); } catch (AlreadyExistsException e) { // view exists: load and commit replace instead }","preventionTips":["Load current metadata before deciding create vs replace commit","Never retry a failed creation with a null base without checking existence","Prefer catalog-level createOrReplace APIs over raw ops.commit"],"tags":["view","already-exists","concurrency","create"],"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"}