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

  1. Re-run the doctor fix — the failed commit rolled back atomically, so a fresh run repeats the deletes safely
  2. Read the wrapped cause: connection errors → restart `dolt sql-server`; storage errors → check disk and Dolt logs
  3. 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)
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/aef2d938d82e9277. Report an issue: GitHub.