gastownhall/beads · error
failed to commit is_blocked repairs: %w
Error message
failed to commit is_blocked repairs: %w
What it means
After the is_blocked recompute succeeds inside the transaction, repairBlockedState calls tx.Commit() to persist the corrected rows to the working set. This error wraps a failed commit; the transaction's changes are lost and nothing was repaired. Note it does not roll back explicitly (commit failure already terminates the tx), and no DOLT_ADD/DOLT_COMMIT staging happens afterward — so the failure is contained to the SQL transaction layer.
Source
Thrown at cmd/bd/doctor/fix/blocked.go:71
return fmt.Errorf("failed to begin transaction: %w", err)
}
// Refuse to derive and commit is_blocked from a dirty graph: like the store
// paths, the recompute reads the working set and stages only `issues`, so a
// dirty issues/dependencies tree would taint the repair commit (bd-6dnrw.37).
// In a `bd doctor --fix` run the dependency-graph fixes commit ahead of this
// one, so the tree is normally clean here; when it is not, surface it as an
// actionable error rather than committing tainted state.
if err := issueops.GuardBlockedRecomputeWorkingSet(ctx, tx); err != nil {
_ = tx.Rollback()
return err
}
changed, err := issueops.RecomputeAllIsBlockedInTx(ctx, tx)
if err != nil {
_ = tx.Rollback()
return fmt.Errorf("failed to recompute is_blocked: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit is_blocked repairs: %w", err)
}
if changed == 0 {
fmt.Println(" is_blocked already consistent — nothing to fix")
return nil
}
// Persist the corrected flags as a Dolt commit, staging only issues — the
// synced table is_blocked lives on (wisps are dolt_ignore'd). This path keeps
// its own fresh-DB lifecycle rather than the shared store helper, but it must
// not report success on a failed commit: a swallowed DOLT_COMMIT error would
// leave the repair in the working set only, silently undone by the next pull.
// bd doctor is server-mode only, so the server supplies the commit identity.
if _, err := db.ExecContext(ctx, "CALL DOLT_ADD(?)", "issues"); err != nil {
return fmt.Errorf("failed to stage is_blocked repairs: %w", err)
}
if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', 'doctor: recompute is_blocked for all issues')"); err != nil && !issueops.IsNothingToCommitError(err) {
return fmt.Errorf("failed to commit is_blocked repairs to Dolt: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped %w cause; if it is a dead/timed-out connection, simply rerun `bd doctor --fix` with a fresh connection.
- Ensure the Dolt server is writable — a read-only server or replica will reject the commit; point bd at the primary.
- Rerun the fix when contention is suspected: commit failures from lock conflicts resolve once the competing process finishes.
- For large databases timing out, increase connection idle/timeout settings or run the repair against the server directly on localhost.
Example fix
// before (read-only replica) err: failed to commit is_blocked repairs: Error 1227: server is running with --read-only // after: target the writable primary beadsDir = primaryBeadsDir // not the replica checkout err := fix.RecomputeBlocked(beadsDir)
Defensive patterns
Strategy: retry
Validate before calling
// Ensure the target server accepts writes before the repair
var readonly int
if err := db.QueryRow("SELECT @@read_only").Scan(&readonly); err == nil && readonly == 1 {
log.Fatal("Dolt server is read-only — point bd at the writable primary")
} Type guard
func isDeadConnCommitErr(err error) bool {
return err != nil && (errors.Is(err, sql.ErrConnDone) ||
strings.Contains(err.Error(), "bad connection") ||
strings.Contains(err.Error(), "driver: timeout"))
} Try / catch
if err := repairBlockedState(ctx, db); err != nil && isDeadConnCommitErr(err) {
// recompute rolled back with the tx — safe to retry on a fresh handle
db.Close()
if db, _, err = openDoltDB(beadsDir); err == nil {
err = repairBlockedState(ctx, db)
}
} Prevention
- Avoid idle timeouts on long recomputes — keep a local/fast connection to the server
- Never point bd at a read-only replica for doctor --fix
- Check for competing lock holders on the issues table before fixing
- Set generous context deadlines for the repair on large databases
When it happens
Trigger: Calling fix.RecomputeBlocked when tx.Commit() fails: the connection to the Dolt server dropped between recompute and commit, the server rejected the commit (lock conflict, deadlock, session killed), the context/deadline expired mid-commit, or the server is read-only (--read-only replica) and refuses writes.
Common situations: Long recompute exceeded a connection idle timeout so the session died before commit; another process held conflicting locks on the issues table; pointing bd at a read-only Dolt replica or a server started read-only; network blip between client and server during a large update.
Related errors
- failed to begin transaction: %w
- ErrTransaction
- failed to recompute is_blocked: %w
- failed to query orphaned dependencies: %w
- row iteration error: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c3744a232703a41b.
Report an issue: GitHub.