gastownhall/beads · error

commit is_blocked recompute: %w

Error message

commit is_blocked recompute: %w

What it means

Wraps a failure of commitWorkingSetAfterSQLCommit when bd commits the recomputed is_blocked values after a pull. The recompute result is derived state that converges across clones and is committed as its own bd commit; if that commit fails for a reason other than 'nothing to commit' (isDoltNothingToCommit), the pull already succeeded but the derived-state commit failed.

Source

Thrown at internal/storage/dolt/store.go:4525

	return s.withCircuitWrite(ctx, func(ctx context.Context) error {
		return s.recomputeBlockedAfterPullUnchecked(ctx, fromCommit)
	})
}

func (s *DoltStore) recomputeBlockedAfterPullUnchecked(ctx context.Context, fromCommit string) error {
	if err := s.recomputeBlockedTx(ctx, fromCommit); err != nil {
		// The merge this recompute covers is already committed, so a plain
		// retry on the next pull would skip as "nothing merged" — leave a
		// marker so it widens its window instead (bd-578h9.11). Best-effort:
		// the recompute error is what matters.
		s.markBlockedRecomputePending(ctx, fromCommit)
		return err
	}
	// Derived state converges: every clone computes the same values from the
	// same merged graph, so committing is merge-safe. Commit no-ops when the
	// recompute changed nothing.
	if err := s.commitWorkingSetAfterSQLCommit(ctx, "bd: recompute is_blocked after pull", configExclude); err != nil && !isDoltNothingToCommit(err) {
		return fmt.Errorf("commit is_blocked recompute: %w", err)
	}
	return nil
}

// RecomputeAllBlocked recomputes is_blocked for every issue and wisp in one full
// pass and returns the number of rows it corrected. It is the mode-independent
// repair behind 'bd recompute-blocked' and 'bd doctor --fix' (bd-6dnrw.37): the
// scoped post-pull recompute is skipped when a re-pull merges nothing, so a
// recompute that failed after its merge committed — or a conflicted pull the
// operator resolved by hand — leaves is_blocked stale until this full pass runs.
// Idempotent: a consistent database corrects nothing.
func (s *DoltStore) RecomputeAllBlocked(ctx context.Context) (int, error) {
	var changed int
	err := s.withCircuitWrite(ctx, func(ctx context.Context) error {
		var err error
		changed, err = s.recomputeAllBlocked(ctx)
		return err
	})

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run `bd dolt pull` — the recompute is idempotent and will be retried
  2. Check for concurrent bd processes and ensure only one writer runs at a time
  3. Inspect the wrapped cause for 'nothing to commit' (harmless) vs real commit failure
  4. Verify the working set has no uncommitted conflicting edits before pulling
Defensive patterns

Strategy: retry

Try / catch

if err := store.Pull(ctx); err != nil {
    if strings.Contains(err.Error(), "commit is_blocked recompute") &&
       !strings.Contains(err.Error(), "nothing to commit") {
        // safe to retry: the recompute commit is idempotent
        err = store.Pull(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: After a successful pull and is_blocked recompute, s.commitWorkingSetAfterSQLCommit returns an error that is not Dolt's 'nothing to commit' — e.g. another writer moved the head (merge conflict on the derived commit), the working set is dirty, or the connection dropped before commit.

Common situations: Concurrent bd processes committing at the same time; pull landed on a stale head; uncommitted local edits present when the recompute ran; transient Dolt server errors during commit.

Related errors


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