gastownhall/beads · error

ClaimReadyIssue: %w

Error message

ClaimReadyIssue: %w

What it means

Wrapped error from the claimReady flow when the standard (non-wisp) repository method ClaimReadyIssue fails. Mirrors the ClaimReadyWisp error at line 1807 but for the regular issues table path. The repository error is preserved via %w for diagnosis.

Source

Thrown at internal/storage/domain/issue.go:1809

func (u *issueUseCaseImpl) ClaimReadyWisp(ctx context.Context, filter types.WorkFilter, actor string) (ClaimReadyResult, error) {
	return u.claimReady(ctx, filter, actor, true)
}

func (u *issueUseCaseImpl) claimReady(ctx context.Context, filter types.WorkFilter, actor string, useWisp bool) (ClaimReadyResult, error) {
	var (
		issue *types.Issue
		err   error
	)
	if useWisp {
		issue, err = u.issueRepo.ClaimReadyWisp(ctx, filter, actor)
	} else {
		issue, err = u.issueRepo.ClaimReadyIssue(ctx, filter, actor)
	}
	if err != nil {
		if useWisp {
			return ClaimReadyResult{}, fmt.Errorf("ClaimReadyWisp: %w", err)
		}
		return ClaimReadyResult{}, fmt.Errorf("ClaimReadyIssue: %w", err)
	}
	return ClaimReadyResult{Issue: issue, Claimed: issue != nil}, nil
}

func (u *issueUseCaseImpl) GetBlockedIssues(ctx context.Context, filter types.WorkFilter) ([]*types.BlockedIssue, error) {
	out, err := u.issueRepo.GetBlockedIssues(ctx, filter)
	if err != nil {
		return nil, fmt.Errorf("GetBlockedIssues: %w", err)
	}
	return out, nil
}

func (u *issueUseCaseImpl) GetStatistics(ctx context.Context) (*types.Statistics, error) {
	out, err := u.issueRepo.GetStatistics(ctx)
	if err != nil {
		return nil, fmt.Errorf("GetStatistics: %w", err)
	}
	return out, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error after 'ClaimReadyIssue:' for the root cause
  2. Validate the WorkFilter (priority range, status, labels) before claiming
  3. Retry on transient storage/lock errors
  4. Check that another process did not corrupt the claim state; re-run bd ready to refresh
Defensive patterns

Strategy: retry

Validate before calling

if filter == (types.WorkFilter{}) {
    return fmt.Errorf("empty WorkFilter for claim")
}

Try / catch

res, err := uc.ClaimReadyIssue(ctx, filter, actor)
if err != nil {
    if isTransient(err) {
        return retryClaim(ctx, filter, actor)
    }
    return fmt.Errorf("claim failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ClaimReadyIssue / ClaimReadyIssueWisp with useWisp=false when issueRepo.ClaimReadyIssue(ctx, filter, actor) errors — invalid filter combination, storage failure during the claim transaction, or the ready-issues query fails.

Common situations: Claiming work with a WorkFilter containing unsupported fields (e.g. bad label syntax); database locked or unreachable; concurrent agents racing to claim the same issue causing constraint violations.

Related errors


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