{"record":{"id":"307394b5ab9e1b0d","repo":"gastownhall/beads","slug":"failed-to-fetch-issues-w","errorCode":null,"errorMessage":"failed to fetch issues: %w","messagePattern":"failed to fetch issues: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/gitlab/client.go","lineNumber":254,"sourceCode":"\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn allIssues, ctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\tparams := map[string]string{\n\t\t\t\"per_page\": strconv.Itoa(MaxPageSize),\n\t\t\t\"page\":     strconv.Itoa(page),\n\t\t}\n\t\tif state != \"\" && state != \"all\" {\n\t\t\tparams[\"state\"] = state\n\t\t}\n\t\tapplyFilter(params, filter)\n\n\t\turlStr := c.buildURL(c.issuesBasePath(), params)\n\t\trespBody, headers, err := c.doRequest(ctx, http.MethodGet, urlStr, nil)\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 issues []Issue\n\t\tif err := json.Unmarshal(respBody, &issues); 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, issues...)\n\n\t\t// Check for next page\n\t\tnextPage := headers.Get(\"X-Next-Page\")\n\t\tif nextPage == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tpage++\n\n\t\t// Guard against infinite pagination loops from malformed responses\n\t\tif page > MaxPages {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/gitlab/client.go#L236-L272","documentation":"FetchIssues calls doRequest to GET the issues endpoint; any failure inside doRequest (auth error, network failure, retries exhausted, malformed request) is wrapped as 'failed to fetch issues'. This is the outer context wrapper - the real cause is in the wrapped chain (e.g. errors 1773-1778).","triggerScenarios":"Any failure of the underlying GET to c.issuesBasePath(): invalid token (401), bad project path (404), rate limit exhausted across retries (429), network outage, or malformed base URL making request creation fail.","commonSituations":"CI jobs with stale tokens; misconfigured GitLab project/group path; syncing during a GitLab outage; hitting secondary rate limits with large pagination loops; base URL missing scheme.","solutions":["Print the full error chain (err with %v or errors.Unwrap) - the wrapped cause names the real problem (status code, network error)","Validate the token: curl -H \"PRIVATE-TOKEN: $TOKEN\" https://gitlab.example/api/v4/user","Verify the configured project path/group resolves in the GitLab UI and is URL-encoded for subgroups","Check connectivity to the instance and whether a 429/5xx outage explains retry exhaustion"],"exampleFix":"// before\nissues, err := client.FetchIssues(ctx, filter)\nlog.Println(err) // failed to fetch issues: API error: 401 ...\n// after\nissues, err := client.FetchIssues(ctx, filter)\nif err != nil {\n\tvar apiErr *gitlab.APIError // or check strings for status\n\tlog.Printf(\"fetch failed: %v\", err) // log full chain\n}","handlingStrategy":"try-catch","validationCode":"if !validBaseURL(cfg.BaseURL) || cfg.Token == \"\" {\n\treturn fmt.Errorf(\"GitLab client misconfigured before FetchIssues\")\n}","typeGuard":"func fetchFailed(err error) bool { return strings.Contains(err.Error(), \"failed to fetch issues\") }","tryCatchPattern":"issues, err := client.FetchIssues(ctx, filter)\nif err != nil {\n\tswitch {\n\tcase strings.Contains(err.Error(), \"status 401\"): refreshToken()\n\tcase strings.Contains(err.Error(), \"transient error\"), strings.Contains(err.Error(), \"max retries\"): scheduleRetry()\n\tdefault: return err\n\t}\n}","preventionTips":["Always unwrap/log the full error chain - this wrapper hides the real cause in its message suffix","Health-check the token and project path before each sync run","Use incremental filters (updated_since) to reduce load and rate-limit pressure","Wrap with your own context timeout so fetches can't hang past the job deadline"],"tags":["fetch","api-error","pagination","gitlab"],"backgroundTag":"failed-to-fetch-issues","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}