gastownhall/beads · error
failed to record claim event: %w
Error message
failed to record claim event: %w
What it means
After a successful claim CAS, ClaimIssueInTx journals a claimed event via RecordFullEventInTable (old/new JSON snapshots) inside the same transaction. This error wraps any failure of that journal write. The claim's row update may be rolled back with the transaction since the event write failed.
Source
Thrown at internal/storage/issueops/claim.go:216
// stops heartbeating and bd reclaim later reverts the issue. Lease rows
// live in the ephemeral leases table (no Dolt commit, node-local). Wisps
// are never leased (they are ephemeral, not reclaimable work).
if !isWisp {
if err := UpsertLeaseInTx(ctx, tx, id, actor, now, leaseTTL(ctx)); err != nil {
return nil, err
}
}
// Record the claim event.
oldData, _ := json.Marshal(oldIssue)
newUpdates := map[string]interface{}{
"assignee": actor,
"status": "in_progress",
}
newData, _ := json.Marshal(newUpdates)
if err := RecordFullEventInTable(ctx, tx, eventTable, id, types.EventClaimed, actor, string(oldData), string(newData)); err != nil {
return nil, fmt.Errorf("failed to record claim event: %w", err)
}
// A claim changes assignee and status, so it journals as an update. The
// idempotent re-claim path returns above without writing and journals
// nothing.
if err := RecordEventInTx(ctx, tx, EventUpdate, id, actor); err != nil {
return nil, err
}
return &ClaimResult{OldIssue: oldIssue, IsWisp: isWisp}, nil
}
// readClaimStateInTx reads one row's coordination columns inside tx — the
// state a lost compare-and-set reports. Shared by the CAS itself and by the
// public claim role, so the two cannot disagree about what "the state that
// refused this claim" means.
//
//nolint:gosec // G201: issueTable comes from WispTableRouting (hardcoded constants)View on GitHub (pinned to 71377f2769)
Solutions
- Retry the claim — the CAS is idempotent for the same actor once in_progress
- Check the event table integrity and DB connectivity (bd doctor)
- Inspect the wrapped driver error for the specific SQL cause
Defensive patterns
Strategy: retry
Validate before calling
// verify DB health before claim bursts
if err := db.PingContext(ctx); err != nil { return err } Try / catch
if err != nil && strings.Contains(err.Error(), "failed to record claim event") {
return retryClaim(ctx, id, actor) // idempotent for same actor
} Prevention
- Don't cancel claim contexts mid-flight; use generous deadlines
- Keep event tables intact across migrations (bd doctor can check)
- Retry the claim — the CAS succeeded or rolled back atomically with the event
When it happens
Trigger: RecordFullEventInTable fails during ClaimIssueInTx — event table missing/corrupt, connection drop mid-transaction, context cancellation, or constraint failure writing the event JSON payload.
Common situations: Interrupted CLI run (canceled context) right after the CAS won; corrupted or migrated-away event table; very large issue JSON exceeding limits on an embedded backend.
Related errors
- db: Claim %s: record event: %w
- failed to claim issue: %w
- failed to get current claim state: %w
- get claimed issue: %w
- ErrExec
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d9204ed8bf43ae9f.
Report an issue: GitHub.