gastownhall/beads · warning
Failed to record push hash for %s: %v
Error message
Failed to record push hash for %s: %v
What it means
recordPushHash (internal/tracker/engine.go:920) is called by doPush after an issue is pushed, to store the pushed content hash via Store.SetLocalMetadata under pushHashKey(issue.ID). That hash is the sync's dirty-check baseline — on the next push, issues whose hash matches are considered unchanged and skipped. If the metadata write fails, the engine warns and returns; the push itself already succeeded, but the issue will look 'unpushed' next time.
Source
Thrown at internal/tracker/engine.go:920
current := e.pushCacheValue(issue, externalRef)
if current == "" {
return false
}
stored, err := e.Store.GetLocalMetadata(ctx, e.pushHashKey(issue.ID))
return err == nil && stored != "" && stored == current
}
// recordPushHash persists the current content-and-target fingerprint for issue
// so subsequent pushes can short-circuit via storedPushHashMatches. No-op when
// ContentHash is unset or returns "", or when the target is empty. Never called
// during dry-run.
func (e *Engine) recordPushHash(ctx context.Context, issue *types.Issue, externalRef string) {
h := e.pushCacheValue(issue, externalRef)
if h == "" {
return
}
if err := e.Store.SetLocalMetadata(ctx, e.pushHashKey(issue.ID), h); err != nil {
e.warn("Failed to record push hash for %s: %v", issue.ID, err)
}
}
func (e *Engine) doPush(ctx context.Context, opts SyncOptions, skipIDs, forceIDs map[string]bool) (*PushStats, error) {
ctx, span := syncTracer.Start(ctx, "tracker.push",
trace.WithAttributes(
attribute.String("sync.tracker", e.Tracker.DisplayName()),
attribute.Bool("sync.dry_run", opts.DryRun),
),
)
defer span.End()
stats := &PushStats{}
// BuildStateCache hook: pre-cache workflow states once before the loop.
// Stored on Engine so tracker adapters can call ResolveState() during push.
e.stateCache = nil
if e.PushHooks != nil && e.PushHooks.BuildStateCache != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Read the `%v` detail; if it is a lock error, close other concurrent bd processes and re-run.
- Re-run `bd push` (or a no-op sync) — the hash write is retried for any issue whose stored hash is still missing.
- Check disk space and that the database file is writable.
- If the backend persistently fails metadata writes, run `bd doctor` to diagnose the storage layer.
- Worst case, force re-push (e.g. --force) so hashes are recomputed and recorded after storage is healthy.
Example fix
// before: parallel bd sync holds the write lock Failed to record push hash for bd-123: database is locked (5) // after: wait for the other process to exit, then bd sync # bd-123 hash recorded; subsequent pushes skip it as unchanged
Defensive patterns
Strategy: retry
Validate before calling
// before pushing, confirm storage is writable and uncontended: bd doctor # and ensure no concurrent bd processes are running
Try / catch
// recordPushHash only warns; detect degraded sync state and recover:
if strings.Contains(warnOutput, "Failed to record push hash") {
time.Sleep(2 * time.Second)
exec.Command("bd", "push").Run() // re-run so hashes are written; unchanged issues re-pushed once
} Prevention
- Serialize bd commands; never run push while another sync is active.
- Keep adequate disk space and verify DB file permissions.
- Re-run push after any storage-level warning so hash bookkeeping converges.
- Use --force only after storage health is confirmed, to rebuild hashes.
When it happens
Trigger: Any `bd push`/sync that completes an issue push and then fails the SetLocalMetadata write — DB write lock held by another bd process, storage closed/unavailable, disk full, or metadata-key constraint failures in the local-metadata table.
Common situations: Concurrent `bd` commands racing on the same database; read-only or full disk; the storage connection dropped mid-sync; embedding the engine with a storage backend that errors on local-metadata writes.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6e1b9e4a2450037e.
Report an issue: GitHub.