{"record":{"id":"8b420e8dd93ac332","repo":"gastownhall/beads","slug":"cascade-repair-s-w","errorCode":null,"errorMessage":"cascade-repair %s: %w","messagePattern":"cascade-repair (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/mergesettle.go","lineNumber":870,"sourceCode":"\n\t// Validate every violating table before touching any of them.\n\tfor _, t := range tables {\n\t\tif _, ok := fkCascadeRepairDeletes[t]; !ok {\n\t\t\treturn false, true, nil\n\t\t}\n\t\tissueFKOnly, err := violationsAreIssueFKOnly(ctx, db, t)\n\t\tif err != nil {\n\t\t\treturn false, true, err\n\t\t}\n\t\tif !issueFKOnly {\n\t\t\treturn false, true, nil\n\t\t}\n\t}\n\n\tfor _, t := range tables {\n\t\tres, err := db.ExecContext(ctx, fkCascadeRepairDeletes[t])\n\t\tif err != nil {\n\t\t\treturn false, true, fmt.Errorf(\"cascade-repair %s: %w\", t, err)\n\t\t}\n\t\tn, _ := res.RowsAffected()\n\t\t// t is from the fixed fkCascadeRepairDeletes allowlist, never user input.\n\t\t//nolint:gosec // G201/G202: hardcoded table name.\n\t\tif _, err := db.ExecContext(ctx, \"DELETE FROM dolt_constraint_violations_\"+t); err != nil {\n\t\t\treturn false, true, fmt.Errorf(\"clear %s constraint violations: %w\", t, err)\n\t\t}\n\t\t//nolint:gosec // G202: hardcoded table name.\n\t\tif _, err := db.ExecContext(ctx, \"CALL DOLT_ADD('\"+t+\"')\"); err != nil {\n\t\t\treturn false, true, fmt.Errorf(\"stage repaired %s: %w\", t, err)\n\t\t}\n\t\tfmt.Fprintf(os.Stderr,\n\t\t\t\"Notice: pull merged %s row(s) referencing issue(s) deleted on another clone; applied the foreign key's cascade delete (%d row(s) removed)\\n\",\n\t\t\tt, n)\n\t}\n\n\t// The repair must leave nothing behind: a residual violation here means the\n\t// deletes above did not cover the constraint that fired, and committing","sourceCodeStart":852,"sourceCodeEnd":888,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/mergesettle.go#L852-L888","documentation":"TryRepairFKCascadeViolations repairs foreign-key constraint violations caused by pull merges by deleting orphaned rows, then clearing the recorded violations. This error wraps a failure of the per-table cascade delete statement (from the fkCascadeRepairDeletes allowlist). The repair aborted for that table and the merge settlement reports repair-failed.","triggerScenarios":"The hardcoded DELETE for table t fails — e.g. additional constraint violations on the row, engine-level FK enforcement rejecting the delete, table doesn't exist after a schema merge, or lock/transaction errors.","commonSituations":"Pull merged issues referencing other issues deleted on another clone; concurrent writer holds locks; Dolt engine refuses deletes while constraint violations are recorded for that table.","solutions":["Inspect the wrapped %w driver error for the actual SQL failure reason.","Run the DELETE manually inside a transaction to see which rows/constraints block it.","Check dolt_constraint_violations_<table> contents to confirm the violations are FK-only before repair.","Retry the merge/settle after the blocking transaction ends."],"exampleFix":"// before: single-shot delete\nres, err := db.ExecContext(ctx, fkCascadeRepairDeletes[t])\n// after: verify violation type first and surface engine detail\nok, err := violationsAreIssueFKOnly(ctx, db, t)\nif err != nil || !ok {\n    return false, false, fmt.Errorf(\"cascade-repair %s: violations not FK-only, refusing auto-delete\", t)\n}","handlingStrategy":"try-catch","validationCode":"var n int\n_ = db.QueryRow(\"SELECT COUNT(*) FROM dolt_constraint_violations WHERE `table` = ? AND num_violations > 0\", \"issues\").Scan(&n)\n// if n > 0, inspect violations manually before enabling auto-repair","typeGuard":null,"tryCatchPattern":"repaired, hasConflicts, err := TryRepairFKCascadeViolations(ctx, db)\nif err != nil && strings.Contains(err.Error(), \"cascade-repair\") {\n    // inspect dolt_constraint_violations_<table> by hand; do not force-settle\n    return manualViolationReview(err)\n}","preventionTips":["Don't delete referenced issues on one clone while another pulls","Run `bd doctor`-style checks after pulls with schema changes","Inspect dolt_constraint_violations before enabling cascade repair"],"tags":["dolt","foreign-key","cascade-delete","merge-repair"],"backgroundTag":"fk-cascade-repair-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}