{"record":{"id":"e4e901c1ef58cee3","repo":"gastownhall/beads","slug":"pagination-limit-exceeded-stopped-after-d-pages-e4e901","errorCode":null,"errorMessage":"pagination limit exceeded: stopped after %d pages","messagePattern":"pagination limit exceeded: stopped after (.+?) pages","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/jira/client.go","lineNumber":183,"sourceCode":"// SearchIssues queries Jira using JQL and returns all matching issues, handling pagination.\nfunc (c *Client) SearchIssues(ctx context.Context, jql string) ([]Issue, error) {\n\tvar allIssues []Issue\n\tstartAt := 0\n\tnextPageToken := \"\"\n\tmaxResults := 100\n\tpage := 0\n\tuseV2Pagination := c.APIVersion == \"2\"\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn allIssues, ctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\tpage++\n\t\tif page > MaxPages {\n\t\t\treturn nil, fmt.Errorf(\"pagination limit exceeded: stopped after %d pages\", MaxPages)\n\t\t}\n\n\t\tparams := url.Values{\n\t\t\t\"jql\":        {jql},\n\t\t\t\"fields\":     {searchFields},\n\t\t\t\"maxResults\": {fmt.Sprintf(\"%d\", maxResults)},\n\t\t}\n\t\tif useV2Pagination {\n\t\t\tparams.Set(\"startAt\", fmt.Sprintf(\"%d\", startAt))\n\t\t} else if nextPageToken != \"\" {\n\t\t\tparams.Set(\"nextPageToken\", nextPageToken)\n\t\t}\n\n\t\t// v3 uses /search/jql; v2 uses /search (both accept jql as a query param)\n\t\tsearchPath := \"search/jql\"\n\t\tif useV2Pagination {\n\t\t\tsearchPath = \"search\"\n\t\t}","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/jira/client.go#L165-L201","documentation":"SearchIssues aborts when pagination exceeds MaxPages iterations, returning nil results. The library enforces this as a runaway-loop guard so a JQL query whose pagination never terminates (or whose result set is enormous) cannot hang the caller forever. It is a deliberate safety limit, not a server error.","triggerScenarios":"Calling SearchIssues with a JQL matching more issues than MaxPages * maxResults (100 per page), or a server whose pagination signal (Total / nextPageToken / isLast) never indicates completion.","commonSituations":"Overly broad JQL like project = X order by updated on a huge instance; a broken next-page token loop on Jira Cloud; API version mismatch (v2/v3 pagination semantics) causing the termination check never to fire.","solutions":["Narrow the JQL: add time bounds (updated >= -7d), project, or component filters to reduce result count.","Increase MaxPages if the limit is legitimately too low for your dataset.","Check that c.APIVersion matches your deployment so the correct pagination mode (startAt vs nextPageToken) is used.","Process results in batches with multiple targeted searches instead of one giant query."],"exampleFix":"// before\nissues, err := client.SearchIssues(ctx, \"project = BIGPROJECT\")\n// after: bound the query window\nissues, err := client.SearchIssues(ctx, \"project = BIGPROJECT AND updated >= -30d ORDER BY updated ASC\")","handlingStrategy":"validation","validationCode":"// Estimate result size before searching:\ntotal, err := countIssues(client, jql) // run jql with maxResults=0 to read Total\nif total > 5000 {\n    return fmt.Errorf(\"JQL matches %d issues; narrow the query or batch by time window\", total)\n}","typeGuard":"func isPaginationLimit(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"pagination limit exceeded\")\n}","tryCatchPattern":"issues, err := client.SearchIssues(ctx, jql)\nif isPaginationLimit(err) {\n    // fall back to time-sliced queries\n    for _, window := range timeWindows(30 * 24 * time.Hour) {\n        slice, e := client.SearchIssues(ctx, jql+\" AND updated >= \"+window[0]+\" AND updated <= \"+window[1])\n        if e != nil { return e }\n        issues = append(issues, slice...)\n    }\n    return nil\n}","preventionTips":["Always scope JQL by project and a time window","Check the search Total first with maxResults=0 before paginating fully","Set MaxPages deliberately to match expected dataset size","Keep APIVersion consistent with pagination semantics (v2 startAt vs v3 nextPageToken)"],"tags":["jira","pagination","jql","go"],"backgroundTag":"pagination-limit-exceeded","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}