{"record":{"id":"6c32c873032e9446","repo":"gastownhall/beads","slug":"pull-merge-left-constraint-violations-bd-cannot-au-6c32c8","errorCode":null,"errorMessage":"pull merge left constraint violations bd cannot auto-repair; inspect dolt_constraint_violations and resolve before retrying","messagePattern":"pull merge left constraint violations bd cannot auto-repair; inspect dolt_constraint_violations and resolve before retrying","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/mergesettle.go","lineNumber":197,"sourceCode":"\t// whose parent issue was deleted on the other clone). Unrepaired\n\t// violations MUST NOT survive: with the force flag on, every statement\n\t// autocommits, so the abort below is what keeps them out of the database.\n\t// This also covers violations a strategy resolution left behind (e.g.\n\t// --ours keeps a child row whose parent was deleted on the other side).\n\trepairedViol, hadViol, violErr := TryRepairFKCascadeViolations(ctx, db)\n\tif violErr != nil {\n\t\tabortMerge(ctx, db, preMergeClean)\n\t\tif mergeErr != nil {\n\t\t\treturn mergeErr\n\t\t}\n\t\treturn violErr\n\t}\n\tif hadViol && !repairedViol {\n\t\tabortMerge(ctx, db, preMergeClean)\n\t\tif mergeErr != nil {\n\t\t\treturn mergeErr\n\t\t}\n\t\treturn fmt.Errorf(\"pull merge left constraint violations bd cannot auto-repair; inspect dolt_constraint_violations and resolve before retrying\")\n\t}\n\n\tif mergeErr != nil && !resolved && !strategyResolved && !repairedViol {\n\t\t// Merge failed for a non-conflict reason, or conflicts include non-metadata tables.\n\t\tabortMerge(ctx, db, preMergeClean)\n\t\treturn mergeErr\n\t}\n\n\t// Conclude the merge for resolved conflicts only now, after the FK repair:\n\t// DOLT_COMMIT refuses a violated working set, so a merge carrying both\n\t// classes could never settle when the resolver committed first (bd-578h9.14).\n\tswitch {\n\tcase resolved:\n\t\tif err := CommitResolvedConflicts(ctx, db); err != nil {\n\t\t\tabortMerge(ctx, db, preMergeClean)\n\t\t\tif mergeErr != nil {\n\t\t\t\treturn mergeErr\n\t\t\t}","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/mergesettle.go#L179-L215","documentation":"After resolving conflicts, SettleMerge attempts to repair FK cascade violations (child rows referencing issues deleted on another clone). This error is returned when violations exist (hadViol=true) but none could be repaired (repairedViol=false) — i.e. the violations have a shape bd cannot handle (non-FK type, unknown table, FK to a parent other than issues). The merge is aborted so no violated working set is committed.","triggerScenarios":"A pull/merge whose result leaves constraint violations outside the known issues-FK cascade class: unique-key violations, FKs to non-issues parents, or violations on tables not in the repair allowlist.","commonSituations":"Two clones where one deleted an issue and the other added rows referencing it via a schema bd does not recognize; a schema extension adding custom FKs; mixed bd versions with divergent schemas.","solutions":["Re-open the database and query `SELECT * FROM dolt_constraint_violations` plus the per-table dolt_constraint_violations_<table> tables to see exactly what violates","Resolve manually: delete or restore the offending rows, clear the violations tables, then retry the pull","Check for schema forks — verify both clones run the same bd version and applied the same migrations (bd doctor reports Migration Content Skew)","If violations are a legit issues-FK cascade case, upgrade bd — newer versions extend the repair allowlist"],"exampleFix":"// after a failed pull, inspect manually:\n// SELECT `table`, num_violations FROM dolt_constraint_violations WHERE num_violations > 0;\n// SELECT * FROM dolt_constraint_violations_dependencies;\n// delete dangling rows, then:\nerr := versioncontrolops.MergeAndSettle(ctx, db, ref)","handlingStrategy":"fallback","validationCode":"// before pulling, check schema consistency across clones (same bd version + migrations)\n// bd doctor reports Migration Content Skew; also pre-check existing violations:\nrows, _ := db.QueryContext(ctx, \"SELECT `table` FROM dolt_constraint_violations WHERE num_violations > 0\")\n// any rows here mean an earlier merge left state the pull cannot auto-repair","typeGuard":"func isUnrepairableViolations(err error) bool {\n\treturn strings.Contains(err.Error(), \"constraint violations bd cannot auto-repair\")\n}","tryCatchPattern":"err := versioncontrolops.MergeAndSettle(ctx, db, ref)\nif err != nil && isUnrepairableViolations(err) {\n\t// operator path: inspect dolt_constraint_violations, delete/restore rows manually,\n\t// clear the violations tables, then retry the pull\n\treturn fmt.Errorf(\"manual constraint repair required: %w\", err)\n}","preventionTips":["Keep all clones on the same bd version so schemas and FK sets match","Run bd doctor regularly to catch migration/content skew early","After this error, query dolt_constraint_violations and per-table violation tables before retrying","Avoid custom FKs to tables outside bd's known child-table set"],"tags":["dolt","foreign-key","merge-conflicts"],"backgroundTag":"constraint-violations-unresolved","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}