gastownhall/beads · error
failed to commit cross-table duplicate removals: %w
Error message
failed to commit cross-table duplicate removals: %w
What it means
CrossTableDuplicates deletes child rows (labels, events, dependencies, comments) then the stale issues row for each duplicate ID inside one transaction; tx.Commit() failure is wrapped as "failed to commit cross-table duplicate removals: %w". On this error nothing is persisted — the stale issues-table copies remain — and the fix returns an error instead of the "Fixed N" summary.
Source
Thrown at cmd/bd/doctor/fix/validation.go:288
// Delete child rows first (FK-safe order), then the issues row.
for _, childTable := range []string{"labels", "events", "dependencies", "comments"} {
//nolint:gosec // G202: childTable is from a hardcoded list above.
if _, err := tx.Exec(fmt.Sprintf("DELETE FROM %s WHERE issue_id = ?", childTable), id); err != nil {
fmt.Printf(" Warning: failed to delete %s rows for %s: %v\n", childTable, id, err)
}
}
if _, err := tx.Exec("DELETE FROM issues WHERE id = ?", id); err != nil {
fmt.Printf(" Warning: failed to delete issues row for %s: %v\n", id, err)
} else {
removed++
if showIndividual {
fmt.Printf(" Removed stale issues-table copy of %s (canonical in wisps)\n", id)
}
}
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit cross-table duplicate removals: %w", err)
}
_, _ = db.Exec("CALL DOLT_COMMIT('-Am', 'doctor: remove stale issues copies of wisps (be-iabdi)')") // Best effort
fmt.Printf(" Fixed %d cross-table duplicate(s)\n", removed)
return nil
}
// CountCrossTableDuplicates returns the number of IDs present in both the
// issues and wisps tables. Returns 0 and an error if the database is
// unreachable. Used by CheckCrossTableDuplicates in the doctor package.
func CountCrossTableDuplicates(path string) (int, error) {
beadsDir, err := resolvedWorkspaceBeadsDir(path)
if err != nil {
return 0, err
}
db, _, err := openDoltDB(beadsDir)View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the doctor fix — the failed commit rolled back atomically, so a fresh run repeats the deletes safely
- Read the wrapped cause: connection errors → restart `dolt sql-server`; storage errors → check disk and Dolt logs
- If FK errors block deletes, ensure child tables are cleaned in the FK-safe order the fix already uses (or relax server FK mode temporarily)
- Avoid interrupting the doctor process between Begin and Commit
Defensive patterns
Strategy: try-catch
Try / catch
if err := tx.Commit(); err != nil {
_ = tx.Rollback()
// commit failure rolled back atomically: safe to re-run the whole fix
return fmt.Errorf("failed to commit cross-table duplicate removals: %w", err)
} Prevention
- Don't interrupt the doctor process between Begin and Commit
- Check disk space and Dolt health before bulk cross-table deletes
- On commit failure, always re-run the fix instead of manual row surgery
- Keep commit windows short by batching reasonable duplicate counts per run
When it happens
Trigger: tx.Commit() fails after the batch of DELETEs: connection dropped during commit, the transaction was implicitly rolled back by an earlier server error, or the Dolt server refused to finalize (storage/FK/autocommit-mode issues).
Common situations: Dolt server restart mid-fix; disk-full or Dolt storage errors at commit; FK enforcement rejecting a delete sequence on non-doctor schemas; network interruption at commit time.
Related errors
- failed to commit dependency key repairs: %w
- failed to commit orphaned dependency removals: %w
- failed to commit dependency removals: %w
- ErrTransaction
- failed to begin transaction: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/aef2d938d82e9277.
Report an issue: GitHub.