gastownhall/beads · error
%w: claim next does not take a limit
Error message
%w: claim next does not take a limit
What it means
ValidateClaimNextRequest rejects claim-next requests that set a Limit on the work filter, wrapping storage.ErrValidation. Claim delivers exactly one issue, so a limit is meaningless here; the shared validator enforces this uniformly across backends so the contract does not drift.
Source
Thrown at internal/storage/issueops/claim_next.go:29
)
// ClaimNextCommitMessage names the claim in the Dolt commit message, matching
// what the CLI's own per-command commit wrote before the claim moved onto the
// role. It is the only spelling: the id it names is the one the claim WON, so
// no caller could have composed it before the call.
func ClaimNextCommitMessage(issueID string) string {
return "bd: claim ready " + issueID
}
// ValidateClaimNextRequest applies the request rules every ReadyClaimer
// implementation shares. It lives here rather than in each of them because a
// rule enforced on one backend and not the other is not a contract.
func ValidateClaimNextRequest(request publicops.ClaimNextRequest) error {
if request.Actor == "" {
return fmt.Errorf("%w: claim next requires an actor", storage.ErrValidation)
}
if request.Filter.Limit != nil {
return fmt.Errorf("%w: claim next does not take a limit", storage.ErrValidation)
}
if request.Filter.Offset != 0 {
return fmt.Errorf("%w: claim next does not take an offset", storage.ErrValidation)
}
// Brief is refused for the reason Limit and Offset are, and the reason is
// sharper here: a claim does not read its row through the page's query at
// all. ExecuteClaimNext refetches the winning row whole (GetIssueInTx) and
// hydrates its counts itself, so the projection has nothing to apply to,
// and a claim that accepted the field would answer a MUTATING request with
// a fully-hydrated row carrying IsLitePartial=false — the caller's only
// signal that it did not get what it asked for, saying it did.
if request.Filter.Brief {
return fmt.Errorf("%w: claim next does not take a projection", storage.ErrValidation)
}
return nil
}
// ExecuteClaimNext claims the first ready issue matching filter in tx, hydratesView on GitHub (pinned to 71377f2769)
Solutions
- Clear Filter.Limit (set to nil) before passing the filter to claim next
- Build a dedicated claim filter instead of reusing a list/ready pagination filter
- Note that ClaimReadyIssueInTx already zeroes Limit/MaxRows internally — avoid pre-setting them
Example fix
// before
filter := types.WorkFilter{Status: &open, Limit: &limit}
err := ValidateClaimNextRequest(publicops.ClaimNextRequest{Filter: filter})
// after
filter := types.WorkFilter{Status: &open}
filter.Limit = nil // claim delivers exactly one issue
err := ValidateClaimNextRequest(publicops.ClaimNextRequest{Filter: filter}) Defensive patterns
Strategy: validation
Validate before calling
func sanitizeClaimFilter(f types.WorkFilter) types.WorkFilter {
f.Limit = nil
f.Offset = 0
f.Brief = false
return f
}
// then: ValidateClaimNextRequest(publicops.ClaimNextRequest{Filter: sanitizeClaimFilter(f), Actor: actor}) Try / catch
if err := ValidateClaimNextRequest(req); err != nil {
if errors.Is(err, storage.ErrValidation) {
req.Filter.Limit = nil
return ValidateClaimNextRequest(req)
}
return err
} Prevention
- Never reuse list/ready pagination filters for claim requests
- Remember claim returns exactly one issue — no pagination knobs apply
- Run ValidateClaimNextRequest before any ReadyClaimer call in shared code paths
When it happens
Trigger: Calling a ReadyClaimer with ClaimNextRequest whose Filter.Limit is non-nil — e.g. reusing a list/ready page filter (with pagination set) as the claim filter.
Common situations: Scripts that build one types.WorkFilter for both `bd list` (paged) and claim; copying a ready-query filter into the claim request without clearing Limit/Offset/Brief; API consumers applying a BEADS_MAX_ROWS cap to the claim filter.
Related errors
- Unclaim: id must not be empty
- UnclaimIfAssignee: id must not be empty
- %w: claim cannot use expected assignee or status
- ErrNotClaimable
- %w: claim next requires an actor
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/fe6649b4243da2eb.
Report an issue: GitHub.