gastownhall/beads · error

ClaimReadyWisp: %w

Error message

ClaimReadyWisp: %w

What it means

Wrapped error from the claimReady flow when the wisp-specific repository method ClaimReadyWisp fails. The use-case branches on useWisp and labels the failure 'ClaimReadyWisp:' so callers can tell which storage path failed. The repository error is preserved via %w.

Source

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

}

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)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error after 'ClaimReadyWisp:' for the root cause
  2. Validate the WorkFilter fields are applicable to wisps before claiming
  3. Retry on transient lock/conflict errors; claims are idempotent per issue
  4. Fall back to the non-wisp claim path if wisps are not enabled
Defensive patterns

Strategy: retry

Validate before calling

if filter == (types.WorkFilter{}) || useWisp && !wispsEnabled {
    return fmt.Errorf("invalid claim configuration")
}

Try / catch

res, err := uc.ClaimReadyIssueWisp(ctx, filter, actor)
if err != nil {
    if isTransient(err) {
        time.Sleep(backoff); goto retry
    }
    log.Warnf("claim failed: %v", err)
    return ClaimReadyResult{}
}

Prevention

When it happens

Trigger: Calling ClaimReadyIssue / ClaimReadyIssueWisp with useWisp=true when issueRepo.ClaimReadyWisp(ctx, filter, actor) errors — e.g. no eligible wisp row can be locked/updated, filter is invalid for wisps, or the storage write fails.

Common situations: Agent work-claiming (bd ready / claim) against the wisps table with filters no wisp satisfies but expressed invalidly; concurrent claimers causing row-lock conflicts; actor string issues in storage.

Related errors


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