{"record":{"id":"97f779b86ca7cada","repo":"gastownhall/beads","slug":"pull-succeeded-but-is-blocked-recompute-failed-w-97f779","errorCode":null,"errorMessage":"pull succeeded but is_blocked recompute failed: %w","messagePattern":"pull succeeded but is_blocked recompute failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/embeddeddolt/version_control.go","lineNumber":664,"sourceCode":"\t\t\t\t// empty here; the conflicts arrive captured pre-abort inside\n\t\t\t\t// MergeConflictsError instead.\n\t\t\t\tvar mce *versioncontrolops.MergeConflictsError\n\t\t\t\tif errors.As(pullErr, &mce) {\n\t\t\t\t\tconflicts = mce.Conflicts\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"pull from %s: %w\", peer, pullErr)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t})\n\tif err != nil || len(conflicts) > 0 {\n\t\t// Conflicted pulls skip the recompute: the operator resolves first,\n\t\t// and the next sync picks the rows up.\n\t\treturn conflicts, err\n\t}\n\tif err := s.recomputeBlockedAfterPull(ctx, preHead); err != nil {\n\t\treturn conflicts, fmt.Errorf(\"pull succeeded but is_blocked recompute failed: %w\", err)\n\t}\n\treturn conflicts, nil\n}\n\n// preMergeHead reads the pre-pull HEAD for the post-merge is_blocked\n// recompute (bd-6dnrw.3). Empty on failure, which degrades the recompute to a\n// full pass instead of skipping the hook.\nfunc (s *EmbeddedDoltStore) preMergeHead(ctx context.Context) string {\n\thead, err := s.GetCurrentCommit(ctx)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn head\n}\n\n// recomputeBlockedAfterPull recomputes the denormalized is_blocked column for\n// the rows a pull's merge changed (bd-6dnrw.3) and creates a Dolt commit for\n// the result. is_blocked is otherwise maintained only by local write paths, so","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/embeddeddolt/version_control.go#L646-L682","documentation":"Returned when the pull itself succeeded but the post-merge recomputation of is_blocked dependencies (recomputeBlockedAfterPull) failed. The data is merged, but derived is_blocked rows may be stale until the next sync. The error is wrapped so the operator knows the merge is fine and only the derived-state refresh broke.","triggerScenarios":"PullFrom completes without conflicts, preMergeHead captured a pre-pull HEAD, and recomputeBlockedAfterPull errors — e.g. SQL query failure, transaction abort, or database contention during recompute.","commonSituations":"Heavy concurrent sync traffic locking rows during recompute; schema drift where is_blocked columns changed; crash/interruption mid-recompute leaving derived state stale.","solutions":["Retry the pull (or trigger the next sync) — recompute reruns and picks the rows up","Inspect the wrapped error for SQL/transaction root cause","Verify dependency schema (is_blocked columns) is intact after upgrades","Run a manual recompute/doctor pass to refresh derived state"],"exampleFix":"// before: treating this as a full pull failure\nif err := store.PullFrom(ctx, peer); err != nil { rollbackEverything() }\n// after: pull data is valid; treat as warning and resync later\nif err := store.PullFrom(ctx, peer); err != nil {\n    log.Warn(\"pull ok but blocked-recompute failed; will retry on next sync: %%v\", err)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"conflicts, err := store.PullFrom(ctx, peer)\nif err != nil && strings.Contains(err.Error(), \"is_blocked recompute failed\") {\n    log.Warn(\"data merged; derived state stale, retrying on next sync\")\n}","preventionTips":["Schedule syncs to avoid heavy concurrency","Recompute proactively after schema migrations","Monitor for repeated recompute failures as a schema-drift signal"],"tags":["go","dolt","pull","dependency-graph"],"backgroundTag":"derived-state-recompute-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}