{"record":{"id":"1c9474a60e9a9e69","repo":"gastownhall/beads","slug":"delete-s-orphans-w","errorCode":null,"errorMessage":"delete %s orphans: %w","messagePattern":"delete (.+?) orphans: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor/fix/clone_local_fks.go","lineNumber":156,"sourceCode":"\tsevered, err := scanSeveredCloneLocalFKs(db)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(severed) == 0 {\n\t\tfmt.Println(\"  ✓ All clone-local FKs present\")\n\t\treturn nil\n\t}\n\n\tfor _, fk := range severed {\n\t\tif fk.Orphans > 0 {\n\t\t\t//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec, not user input.\n\t\t\tdeleteOrphans := fmt.Sprintf(\n\t\t\t\t`DELETE FROM %s WHERE %s IS NOT NULL AND NOT EXISTS (SELECT 1 FROM %s r WHERE r.%s = %s.%s)`,\n\t\t\t\tfk.Table, fk.Column, fk.RefTable, fk.RefColumn, fk.Table, fk.Column,\n\t\t\t)\n\t\t\tresult, err := db.Exec(deleteOrphans)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"delete %s orphans: %w\", fk.Table, err)\n\t\t\t}\n\t\t\tif verbose {\n\t\t\t\tremoved, _ := result.RowsAffected()\n\t\t\t\tfmt.Printf(\"  Removed %d orphaned row(s) from %s\\n\", removed, fk.Table)\n\t\t\t}\n\t\t}\n\n\t\t//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec, not user input.\n\t\taddConstraint := fmt.Sprintf(\n\t\t\t`ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) ON DELETE CASCADE ON UPDATE CASCADE`,\n\t\t\tfk.Table, fk.Constraint, fk.Column, fk.RefTable, fk.RefColumn,\n\t\t)\n\t\tif _, err := db.Exec(addConstraint); err != nil {\n\t\t\treturn fmt.Errorf(\"re-add %s.%s: %w\", fk.Table, fk.Constraint, err)\n\t\t}\n\t\tfmt.Printf(\"  ✓ Re-linked %s.%s (%d orphaned row(s) removed)\\n\", fk.Table, fk.Constraint, fk.Orphans)\n\t}\n\treturn nil","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/fix/clone_local_fks.go#L138-L174","documentation":"relinkSeveredCloneLocalFKs deletes orphaned rows that would violate the FK before re-adding the constraint. If the generated DELETE fails, this error wraps it and aborts the relink, leaving the constraint absent and orphans in place.","triggerScenarios":"The dynamic DELETE of orphan rows fails in relinkSeveredCloneLocalFKs (cmd/bd/doctor/fix/clone_local_fks.go:156) during CloneLocalFKEnforcement — write permission denied, storage locked, or ON DELETE CASCADE side effects rejected by the engine.","commonSituations":"Read-only database or filesystem permissions on .beads, a concurrent bd process holding Dolt write locks, or FK validation errors from other constraints on the rows being deleted.","solutions":["Check the wrapped driver error for permission/lock problems; ensure the workspace is writable and no other bd process is running.","Re-run `bd doctor` (fix mode) once write access is restored — the delete is idempotent per scan.","If other FKs block deletion, resolve those constraints first (run the scan again to see all severed FKs).","Restore the .beads Dolt store from backup if the write failure indicates corruption."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure writable DB and no competing writers before relink:\nif err := db.Ping(); err != nil { return err }\n// verify write access\nif _, err := db.Exec(`SELECT 1 FOR UPDATE`); err != nil { /* lock/perm check failed */ }","typeGuard":null,"tryCatchPattern":"if err := CloneLocalFKEnforcement(ctx, db, verbose); err != nil && strings.Contains(err.Error(), \"delete\") {\n\t// orphan delete failed: check permissions/locks, then re-run fix\n\treturn err\n}","preventionTips":["Ensure the database user has DELETE privileges on issues tables","Stop other bd processes before running fix mode","Keep the .beads filesystem writable (not read-only mounted)","Run the scan first (read-only) to preview how many rows will be deleted"],"tags":["dolt","doctor","foreign-keys","delete"],"backgroundTag":"database-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}