{"record":{"id":"16e2244cde43553b","repo":"gastownhall/beads","slug":"failed-to-add-to-waiters-w","errorCode":null,"errorMessage":"failed to add to waiters: %w","messagePattern":"failed to add to waiters: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/merge_slot.go","lineNumber":121,"sourceCode":"\t\t\tif slot.Status != types.StatusOpen {\n\t\t\t\t// Slot is held.\n\t\t\t\tif wait {\n\t\t\t\t\talreadyWaiting := false\n\t\t\t\t\tfor _, w := range meta.Waiters {\n\t\t\t\t\t\tif w == holder {\n\t\t\t\t\t\t\talreadyWaiting = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif !alreadyWaiting {\n\t\t\t\t\t\tmeta.Waiters = append(meta.Waiters, holder)\n\t\t\t\t\t}\n\t\t\t\t\tmetaStr, err := encodeSlotMeta(meta)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"failed to encode slot metadata: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tif err := tx.UpdateIssue(ctx, slot.ID, map[string]interface{}{\"metadata\": metaStr}, actor); err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"failed to add to waiters: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tresult.Waiting = true\n\t\t\t\t\tresult.Position = len(meta.Waiters)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t// Slot is available — acquire it atomically.\n\t\t\tnewMeta := slotMeta{Holder: holder, Waiters: meta.Waiters}\n\t\t\tmetaStr, err := encodeSlotMeta(newMeta)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to encode slot metadata: %w\", err)\n\t\t\t}\n\t\t\tif err := tx.UpdateIssue(ctx, slot.ID, map[string]interface{}{\n\t\t\t\t\"status\":   types.StatusInProgress,\n\t\t\t\t\"metadata\": metaStr,\n\t\t\t}, actor); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to acquire slot: %w\", err)","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/merge_slot.go#L103-L139","documentation":"This error wraps a failed tx.UpdateIssue call that persists the updated waiters list to the merge slot bead's metadata while waiting for the slot. The waiter was computed but could not be written inside the acquire transaction, so the whole transaction rolls back and the caller is not registered as waiting.","triggerScenarios":"MergeSlotAcquire with wait=true while the slot is held, and tx.UpdateIssue on the slot ID fails — e.g. database lock timeout, connection loss mid-transaction, the slot issue was deleted concurrently, or a storage-layer validation rejected the metadata string.","commonSituations":"Two agents contending for the merge slot on a slow or remote Dolt database; slot bead deleted or renamed by manual cleanup; transient DB outage during high-contention merges.","solutions":["Retry MergeSlotAcquire — the transaction is atomic, so retry is safe","Verify the slot exists with 'bd merge-slot create' / bd show of the slot ID","Check database connectivity and lock contention (other long-running transactions)","Inspect the wrapped error (%w) for the root cause from UpdateIssue"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := store.GetIssue(ctx, MergeSlotID(ctx, store)); err != nil || err == nil && slotNil { /* recreate slot */ }","typeGuard":null,"tryCatchPattern":"res, err := store.MergeSlotAcquire(ctx, holder, actor, true)\nif err != nil && strings.Contains(err.Error(), \"failed to add to waiters\") {\n    return retryWithBackoff(func() error { _, err = store.MergeSlotAcquire(ctx, holder, actor, true); return err })\n}","preventionTips":["Verify the merge-slot bead exists before acquiring ('bd merge-slot create' is idempotent)","Keep database connections healthy; check Dolt server reachability under contention","Avoid deleting the internal merge-slot bead during active merges","Always inspect the wrapped cause, not just the wrapper message"],"tags":["go","merge-slot","transaction","storage","update-failed"],"backgroundTag":"slot-update-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}