gastownhall/beads · error
merge succeeded but is_blocked recompute failed: %w
Error message
merge succeeded but is_blocked recompute failed: %w
What it means
Merge completed successfully (no merge errors and no conflicts) in a non-read-only store, but the follow-up recompute of the denormalized is_blocked column (recomputeBlockedAfterPull) failed. The merge itself is durable; only the derived blocked-status data may be stale, so the error is reported as a post-merge failure with the original conflicts still returned alongside it.
Source
Thrown at internal/storage/embeddeddolt/version_control.go:315
func (s *EmbeddedDoltStore) Merge(ctx context.Context, branch string) ([]storage.Conflict, error) {
// bd-578h9.11: like every pull path, a branch merge brings in writes that
// bypassed the local is_blocked hooks; recompute after a conflict-free
// merge. Conflicted merges defer to the caller's post-resolution hook
// (Sync, bd vc merge --strategy) — recomputing over unresolved rows would
// read garbage.
preHead := ""
if !s.readOnly {
preHead = s.preMergeHead(ctx)
}
var conflicts []storage.Conflict
err := s.withMutatingDBConn(ctx, func(db versioncontrolops.DBConn) error {
var err error
conflicts, err = versioncontrolops.Merge(ctx, db, branch, commitAuthor)
return err
})
if err == nil && len(conflicts) == 0 && !s.readOnly {
if rerr := s.recomputeBlockedAfterPull(ctx, preHead); rerr != nil {
return conflicts, fmt.Errorf("merge succeeded but is_blocked recompute failed: %w", rerr)
}
}
return conflicts, err
}
// MergeWithStrategy implements storage.StrategicMerger for `bd vc merge
// --strategy` (#4992). Unlike Merge, it runs on a PINNED session
// (withMutatingPinnedDBConn, not withMutatingDBConn): the conflict-tolerant
// session flags versioncontrolops.MergeWithStrategy sets are session state
// and must be visible to the merge, resolve, repair, and commit statements
// that follow — a *sql.DB pool (OpenSQL allows 2 idle conns) could otherwise
// hand out a different connection mid-sequence.
//
// A resolved merge (conflicted or clean) always commits, so — unlike plain
// Merge, which skips the recompute for a still-conflicted merge — the
// is_blocked recompute always runs on success here.
func (s *EmbeddedDoltStore) MergeWithStrategy(ctx context.Context, branch, strategy string) ([]storage.Conflict, error) {
preHead := ""View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped rerr for the recompute failure cause (SQL error, context cancelled, connection loss) and address that root cause.
- Re-run the recompute to refresh is_blocked — rerunning Sync/merge (which will be a no-op merge) or a dedicated recompute path restores consistency.
- If the context was cancelled, retry with a longer deadline so merge and recompute complete together.
- Check for schema drift on the issues table (is_blocked column) and apply any pending migrations before retrying.
- Verify data consistency manually if is_blocked values look stale: the merge succeeded, only derived columns may be outdated.
Example fix
// before: ignoring post-merge recompute need
conflicts, err := store.Merge(ctx, branch, author)
// after: recover from recompute failure explicitly
conflicts, err := store.Merge(ctx, branch, author)
if err != nil && strings.Contains(err.Error(), "is_blocked recompute failed") {
// merge landed; re-run to refresh derived state
_, err = store.Sync(ctx)
} Defensive patterns
Strategy: try-catch
Try / catch
conflicts, err := store.Merge(ctx, branch, author)
if err != nil {
if strings.Contains(err.Error(), "is_blocked recompute failed") {
// merge landed durably; only derived state is stale.
// process conflicts normally, then trigger a recompute/sync.
_ = refreshBlockedStatus(ctx)
}
return conflicts, err
} Prevention
- Use context budgets that cover the merge AND the post-merge recompute.
- Keep the issues-table schema (is_blocked column) current with migrations.
- Avoid concurrent writes during merge/sync operations.
- After this error, re-run sync or a recompute to refresh is_blocked before trusting blocked-status queries.
When it happens
Trigger: Calling Merge (used by Sync) on an EmbeddedDoltStore where the merge succeeds but recomputeBlockedAfterPull errors — e.g. the recompute SQL fails, the pinned connection is lost mid-recompute, or the context is cancelled between merge and recompute.
Common situations: Network-triggered sync where the context times out right after the merge; database contention during the recompute query; schema/driver errors in the denormalized is_blocked update after schema drift or partial migration.
Related errors
- error merging config file %s: %w
- failed to commit pending changes before pull: %w
- merge failed: %w
- federation filter: recompute staged is_blocked: %w
- pull merge left constraint violations bd cannot auto-repair;
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5723fbd33ad973ae.
Report an issue: GitHub.