gastownhall/beads · error

stage repaired %s: %w

Error message

stage repaired %s: %w

What it means

After clearing constraint violations, the repaired table is staged with CALL DOLT_ADD('<t>') so the fix is part of the merge commit. Failure means the repaired rows are deleted but unstaged, so the merge will not capture the fix. Repair aborts with this wrapped error.

Source

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

		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 {
		return false, true, nil
	}
	return true, true, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped %w error for the engine-side cause.
  2. Run CALL DOLT_ADD('<table>') manually inside the same session to see the raw error.
  3. If the merge is stuck, DOLT_MERGE_ABORT() and redo the pull/settle.
  4. Ensure only one bd/dolt process is operating on the database during settle.

Example fix

// before
if _, err := db.ExecContext(ctx, "CALL DOLT_ADD('"+t+"')"); err != nil {
    return false, true, fmt.Errorf("stage repaired %s: %w", t, err)
}
// after: retry staging once before giving up
if _, err := db.ExecContext(ctx, "CALL DOLT_ADD('"+t+"')"); err != nil {
    if _, rerr := db.ExecContext(ctx, "CALL DOLT_ADD('"+t+"')"); rerr != nil {
        return false, true, fmt.Errorf("stage repaired %s: %w", t, rerr)
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// confirm the table exists in the working set before staging
var one int
_ = db.QueryRow("SELECT 1 FROM issues LIMIT 1").Scan(&one)

Try / catch

if _, _, err := TryRepairFKCascadeViolations(ctx, db); err != nil && strings.Contains(err.Error(), "stage repaired") {
    // rows deleted but unstaged: abort merge and redo the pull
    _, _ = db.ExecContext(ctx, "CALL DOLT_MERGE_ABORT()")
    return retryPull(ctx)
}

Prevention

When it happens

Trigger: DOLT_ADD fails for table t — merge transaction in an inconsistent state, working-set/table not recognized by the engine, server refuses DOLT_ADD inside the current transaction, or table was dropped by the schema side of the merge.

Common situations: Engine/server version differences in DOLT_ADD behavior during a merge; interrupted settle leaving metadata inconsistent; permission or lock conflicts with another bd process.

Related errors


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