gastownhall/beads · error
search issues: %w
Error message
search issues: %w
What it means
SearchIssues wraps errors from doRequest (the HTTP GET to /search/jql or /search). It means the transport layer failed before a body could be parsed: non-2xx status, connection error, timeout, or canceled context. The library wraps it with the search context so callers know the JQL query itself failed at the HTTP level.
Source
Thrown at internal/jira/client.go:206
"fields": {searchFields},
"maxResults": {fmt.Sprintf("%d", maxResults)},
}
if useV2Pagination {
params.Set("startAt", fmt.Sprintf("%d", startAt))
} else if nextPageToken != "" {
params.Set("nextPageToken", nextPageToken)
}
// v3 uses /search/jql; v2 uses /search (both accept jql as a query param)
searchPath := "search/jql"
if useV2Pagination {
searchPath = "search"
}
apiURL := fmt.Sprintf("%s/%s?%s", c.apiBase(), searchPath, params.Encode())
body, err := c.doRequest(ctx, "GET", apiURL, nil)
if err != nil {
return nil, fmt.Errorf("search issues: %w", err)
}
var result SearchResult
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("parse search response: %w", err)
}
allIssues = append(allIssues, result.Issues...)
if len(result.Issues) == 0 {
break
}
if useV2Pagination {
if startAt+len(result.Issues) >= result.Total {
break
}
startAt += len(result.Issues)
continueView on GitHub (pinned to 71377f2769)
Solutions
- Check wrapped error for HTTP status: fix auth (401/403) by regenerating the API token and using account email.
- If 404, set c.APIVersion appropriately ("2" for older Jira Server which lacks /search/jql).
- If 400, validate JQL syntax in the Jira UI search bar first.
- If 429 or timeout, back off and retry with a smaller maxResults or narrower JQL.
Example fix
// before: opaque failure
issues, err := client.SearchIssues(ctx, jql)
// after: retry transient failures
var issues []jira.Issue
err := retry(3, func() error {
var e error
issues, e = client.SearchIssues(ctx, jql)
return e
}) Defensive patterns
Strategy: retry
Validate before calling
// Preflight auth and endpoint before searching:
resp, err := http.Get(client.URL + "/rest/api/3/myself") // expect 200 with valid basic auth
if err != nil || resp.StatusCode != 200 {
return fmt.Errorf("Jira preflight failed: status %d", resp.StatusCode)
} Type guard
func isRateLimit(err error) bool {
return err != nil && (strings.Contains(err.Error(), "429") || strings.Contains(err.Error(), "rate"))
} Try / catch
var issues []jira.Issue
backoff := time.Second
for attempt := 0; attempt < 3; attempt++ {
issues, err = client.SearchIssues(ctx, jql)
if err == nil { break }
if isRateLimit(err) || errors.Is(err, context.DeadlineExceeded) {
time.Sleep(backoff); backoff *= 2; continue
}
return err // non-transient: bad JQL, auth
} Prevention
- Validate JQL in the Jira UI before hard-coding it
- Rotate API tokens before expiry; use account email for Cloud auth
- Match APIVersion to deployment (Server often needs "2")
- Add backoff for 429s and keep maxResults modest during bulk syncs
When it happens
Trigger: Any SearchIssues call where the HTTP request fails: 401/403 (bad API token), 404 (wrong API version path), 400 (malformed JQL), 429 (rate limit), network outage, or 30s client timeout on huge queries.
Common situations: Expired or wrong Atlassian API token; email vs username confusion in basic auth; Jira Server lacking the v3 /search/jql endpoint; JQL syntax errors rejected with 400; rate limiting during bulk syncs.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- get issue %s: %w
- fetch issue %s: %w
- pagination limit exceeded: stopped after %d pages
- create issue: %w
- failed to read response (attempt %d/%d): %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d19785dba0f3cee4.
Report an issue: GitHub.