gastownhall/beads · error

get claimed issue: %w

Error message

get claimed issue: %w

What it means

ClaimReadyIssueInTx claims the first ready issue, then re-reads the claimed row with GetIssueInTx to return the authoritative post-claim state. This error wraps a failure of that follow-up read, meaning the claim likely succeeded but the fresh row could not be fetched inside the same transaction.

Source

Thrown at internal/storage/issueops/claim.go:296

	// here.
	claimFilter.Limit = 0
	claimFilter.MaxRows = 0
	claimFilter.MaxRowsSource = ""

	readyIssues, err := GetReadyWorkInTx(ctx, tx, claimFilter)
	if err != nil {
		return nil, err
	}
	for _, issue := range readyIssues {
		if _, err := ClaimIssueInTx(ctx, tx, issue.ID, actor); err != nil {
			if errors.Is(err, storage.ErrAlreadyClaimed) || errors.Is(err, storage.ErrNotClaimable) {
				continue
			}
			return nil, err
		}
		claimed, err := GetIssueInTx(ctx, tx, issue.ID)
		if err != nil {
			return nil, fmt.Errorf("get claimed issue: %w", err)
		}
		return claimed, nil
	}
	return nil, nil
}

// ClaimPoolAliasesInTx returns the pool pseudo-assignee aliases from the
// claim.pools config key (comma-separated, whitespace-trimmed). An issue
// assigned to one of these aliases is claimable by ANY actor through the
// normal claim CAS — the pattern where a dispatcher pre-assigns work to a
// group alias (e.g. "fable-crew") and members take items from the pool.
// Issues assigned to a real actor are unaffected. Missing/empty config (the
// default) disables pool-aware claiming entirely.
func ClaimPoolAliasesInTx(ctx context.Context, tx DBTX) ([]string, error) {
	raw, err := GetConfigInTx(ctx, tx, "claim.pools")
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry bd claim — a same-actor re-claim is idempotent, so retrying is safe
  2. Check DB connectivity if the wrapped error is a connection failure
  3. Refresh the ready queue and claim a different issue if this one raced away
Defensive patterns

Strategy: retry

Validate before calling

if err := db.PingContext(ctx); err != nil { return fmt.Errorf("db unavailable: %w", err) }

Try / catch

claimed, err := ClaimReadyIssueInTx(ctx, tx, filter, actor)
if err != nil && !errors.Is(err, storage.ErrValidation) {
    return retryClaimNext(ctx, tx, filter, actor) // re-claim is safe/idempotent
}

Prevention

When it happens

Trigger: After ClaimIssueInTx succeeds inside ClaimReadyIssueInTx (via ExecuteClaimNext), GetIssueInTx errors — connection drop, context cancellation, or the row vanished mid-transaction.

Common situations: Flaky connection between the CAS UPDATE and the re-read; a canceled CLI context racing the read; a concurrent transaction that deleted the just-claimed issue.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/761c8ec12bc25680. Report an issue: GitHub.