{"record":{"id":"b585a1e552e5fa4f","repo":"gastownhall/beads","slug":"failed-to-fetch-issues-w-b585a1","errorCode":null,"errorMessage":"failed to fetch issues: %w","messagePattern":"failed to fetch issues: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":506,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"pagination limit exceeded: stopped after %d pages\", MaxPages)\n\t\t}\n\n\t\tvariables := map[string]interface{}{\n\t\t\t\"filter\": filter,\n\t\t\t\"first\":  MaxPageSize,\n\t\t}\n\t\tif cursor != \"\" {\n\t\t\tvariables[\"after\"] = cursor\n\t\t}\n\n\t\treq := &GraphQLRequest{\n\t\t\tQuery:     issuesQuery,\n\t\t\tVariables: variables,\n\t\t}\n\n\t\tdata, err := c.Execute(ctx, req)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to fetch issues: %w\", err)\n\t\t}\n\n\t\tvar issuesResp IssuesResponse\n\t\tif err := json.Unmarshal(data, &issuesResp); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse issues response: %w\", err)\n\t\t}\n\n\t\tallIssues = append(allIssues, issuesResp.Issues.Nodes...)\n\n\t\tif !issuesResp.Issues.PageInfo.HasNextPage {\n\t\t\tbreak\n\t\t}\n\t\tcursor = issuesResp.Issues.PageInfo.EndCursor\n\t}\n\n\treturn allIssues, nil\n}\n","sourceCodeStart":488,"sourceCodeEnd":524,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L488-L524","documentation":"FetchIssues wraps any error from Client.Execute with this message while fetching a page of issues. The wrapped cause is the real failure: GraphQL errors, rate limiting, retries exhausted, HTTP API errors, or context cancellation.","triggerScenarios":"Any Execute failure inside the FetchIssues pagination loop: invalid team ID filter (GraphQL errors), 429 rate-limit storm leading to 'max retries exceeded', network failure, 401/403 auth failures (non-OAuth clients don't retry 401), or HTTP 5xx from Linear.","commonSituations":"Expired or revoked LINEAR_API_KEY; wrong LINEAR_TEAM_ID causing a GraphQL rejection; hitting Linear rate limits during a large sync; transient outage mid-pagination.","solutions":["Unwrap the %w cause — the inner message says exactly which failure occurred","If it's auth-related, regenerate the Linear API key and update configuration","If it's a GraphQL error, check TeamID/ProjectID against the actual workspace","If rate-limited, back off and retry later or reduce sync frequency","Check Linear's status page for outages"],"exampleFix":"// before\nissues, err := client.FetchIssues(ctx, \"open\")\n// after: inspect the wrapped cause\nif err != nil {\n    log.Printf(\"FetchIssues failed: %v\", errors.Unwrap(err))\n    return fmt.Errorf(\"sync aborted: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if client.TeamID == \"\" || token == \"\" {\n    return errors.New(\"linear: missing TEAM_ID or API token\")\n}","typeGuard":null,"tryCatchPattern":"issues, err := client.FetchIssues(ctx, \"open\")\nif err != nil {\n    var root = errors.Unwrap(err)\n    switch {\n    case strings.Contains(err.Error(), \"GraphQL errors:\"):\n        return fmt.Errorf(\"bad filter/config: %w\", err) // do not retry\n    case strings.Contains(err.Error(), \"max retries\"):\n        return retryLater(err) // transient\n    default:\n        return err\n    }\n}","preventionTips":["Validate TeamID/token at client construction with a cheap query","Unwrap errors to branch on the real cause before deciding to retry","Persist sync state so a failed page fetch can resume, not restart","Watch rate-limit headers during bulk operations"],"tags":["linear","network","api-error","pagination"],"backgroundTag":"linear-api-fetch-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}