gastownhall/beads · error

clear %s constraint violations: %w

Error message

clear %s constraint violations: %w

What it means

After cascade-deleting orphaned rows for table t, the repair clears the violation records via DELETE FROM dolt_constraint_violations_<t>. Failure here means rows were repaired but the violation ledger still lists them, leaving the table in a half-repaired state. The error is wrapped and repair aborts for this table.

Source

Thrown at internal/storage/versioncontrolops/mergesettle.go:876

		issueFKOnly, err := violationsAreIssueFKOnly(ctx, db, t)
		if err != nil {
			return false, true, err
		}
		if !issueFKOnly {
			return false, true, nil
		}
	}

	for _, t := range tables {
		res, err := db.ExecContext(ctx, fkCascadeRepairDeletes[t])
		if err != nil {
			return false, true, fmt.Errorf("cascade-repair %s: %w", t, err)
		}
		n, _ := res.RowsAffected()
		// t is from the fixed fkCascadeRepairDeletes allowlist, never user input.
		//nolint:gosec // G201/G202: hardcoded table name.
		if _, err := db.ExecContext(ctx, "DELETE FROM dolt_constraint_violations_"+t); err != nil {
			return false, true, fmt.Errorf("clear %s constraint violations: %w", t, err)
		}
		//nolint:gosec // G202: hardcoded table name.
		if _, err := db.ExecContext(ctx, "CALL DOLT_ADD('"+t+"')"); err != nil {
			return false, true, fmt.Errorf("stage repaired %s: %w", t, err)
		}
		fmt.Fprintf(os.Stderr,
			"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",
			t, n)
	}

	// The repair must leave nothing behind: a residual violation here means the
	// deletes above did not cover the constraint that fired, and committing
	// would persist a violated working set.
	remaining, err := constraintViolationTables(ctx, db)
	if err != nil {
		return false, true, err
	}
	if len(remaining) > 0 {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped %w error — 'table doesn't exist' usually means no violations remained; treat as benign or check dolt_constraint_violations first.
  2. Query SELECT * FROM dolt_constraint_violations WHERE `table`='t' to confirm violations still exist before deleting.
  3. Retry settle after concurrent writers finish.
  4. Upgrade to a Dolt/beads version with matching constraint-violation table handling.

Example fix

// before
if _, err := db.ExecContext(ctx, "DELETE FROM dolt_constraint_violations_"+t); err != nil {
    return false, true, fmt.Errorf("clear %s constraint violations: %w", t, err)
}
// after: only clear when the violations table exists
if _, err := db.ExecContext(ctx, "DELETE FROM dolt_constraint_violations_"+t); err != nil {
    if !strings.Contains(err.Error(), "doesn't exist") {
        return false, true, fmt.Errorf("clear %s constraint violations: %w", t, err)
    } // benign: violations table already gone
}
Defensive patterns

Strategy: try-catch

Validate before calling

var exists int
_ = db.QueryRow("SELECT COUNT(*) FROM information_schema.tables WHERE table_name = ?", "dolt_constraint_violations_issues").Scan(&exists)
// exists == 0 means nothing to clear

Try / catch

if _, _, err := TryRepairFKCascadeViolations(ctx, db); err != nil && strings.Contains(err.Error(), "clear") {
    // half-repaired state: re-run settle from a clean merge
    _, _ = db.ExecContext(ctx, "CALL DOLT_MERGE_ABORT()")
    return err
}

Prevention

When it happens

Trigger: DELETE FROM dolt_constraint_violations_<t> fails — table doesn't exist (no violations actually recorded, engine version mismatch), permission issue, or engine refuses the delete inside the merge transaction.

Common situations: Dolt version where dolt_constraint_violations_<table> is not created unless violations exist; server vs embedded engine behavioral differences; concurrent process already cleared the table and dropped it.

Related errors


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