{"record":{"id":"b732ec783ddb95ea","repo":"apache/iceberg","slug":"failed-to-create-view-s-in-catalog-s","errorCode":null,"errorMessage":"Failed to create view %s in catalog %s","messagePattern":"Failed to create view (.+?) in catalog (.+?)","errorType":"exception","errorClass":"CommitFailedException","httpStatus":409,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java","lineNumber":197,"sourceCode":"          viewIdentifier, catalogName, namespace);\n    }\n\n    if (JdbcUtil.tableExists(JdbcUtil.SchemaVersion.V1, catalogName, connections, viewIdentifier)) {\n      throw new AlreadyExistsException(\"Table with same name already exists: %s\", viewIdentifier);\n    }\n\n    if (JdbcUtil.viewExists(catalogName, connections, viewIdentifier)) {\n      throw new AlreadyExistsException(\"View already exists: %s\", viewIdentifier);\n    }\n\n    int insertRecord =\n        JdbcUtil.doCommitCreateView(\n            connections, catalogName, namespace, viewIdentifier, newMetadataLocation);\n\n    if (insertRecord == 1) {\n      LOG.debug(\"Successfully committed to new view: {}\", viewIdentifier);\n    } else {\n      throw new CommitFailedException(\n          \"Failed to create view %s in catalog %s\", viewIdentifier, catalogName);\n    }\n  }\n}\n","sourceCodeStart":179,"sourceCodeEnd":202,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java#L179-L202","documentation":"After the INSERT in doCommitCreateView, createView expects exactly 1 inserted row. If the insert reports a different row count, a CommitFailedException is thrown, meaning the atomic create-insert did not produce the expected single view row despite pre-checks passing.","triggerScenarios":"Concurrent insert of the same view between viewExists check and the INSERT (insert affected 0 rows due to constraint), or an anomalous driver result (>1 rows affected, e.g. triggers/misbehaving driver).","commonSituations":"Race between two createView calls for the same identifier where the loser's INSERT matches no rows or violates the unique key; database triggers altering affected-row counts; driver-specific rowcount semantics.","solutions":["Refresh catalog state and check whether the view was actually created before retrying","Catch CommitFailedException and retry as an update (load existing view) if the view now exists","Check for a unique-key violation wrapped as the cause — that means a concurrent creator won the race","Remove DB triggers or unusual driver behavior that distort affected-row counts on the catalog tables"],"exampleFix":"// before\nops.commit(newMeta, null); // blind create retry\n// after\ntry {\n  ops.commit(newMeta, null);\n} catch (CommitFailedException e) {\n  if (catalog.viewExists(id)) { /* update path */ } else { /* retry create */ }\n}","handlingStrategy":"retry","validationCode":"// pre-check before create\nif (catalog.viewExists(id)) { /* use update path */ }","typeGuard":null,"tryCatchPattern":"try {\n  viewOps.commit(newMetadata, null);\n} catch (CommitFailedException e) {\n  viewOps.refresh();\n  if (viewOps.current() != null) retryAsUpdate(); else retryCreateWithBackoff();\n}","preventionTips":["Treat create failures as races: re-check catalog state before retrying","Avoid DB triggers on catalog tables that distort affected-row counts","Use a stable JDBC driver known to report accurate update counts"],"tags":["jdbc","commit-conflict","view-creation","race-condition"],"backgroundTag":"invalid-state-transition","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"}