{"record":{"id":"2f4b1eceb92af47c","repo":"wtfutil/wtf","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/buildkite/client.go","lineNumber":63,"sourceCode":"\n\treq, err := http.NewRequest(\"GET\", url, http.NoBody)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Add(\"Authorization\", fmt.Sprintf(\"Bearer %s\", widget.settings.apiKey))\n\n\thttpClient := &http.Client{Transport: &http.Transport{\n\t\tProxy: http.ProxyFromEnvironment,\n\t}}\n\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\t\treturn nil, fmt.Errorf(\"%s\", resp.Status)\n\t}\n\n\tbuilds := []Build{}\n\terr = utils.ParseJSON(&builds, resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn builds, nil\n}\n\nfunc branchesQuery(branches []string) string {\n\tif len(branches) == 0 {\n\t\treturn \"\"\n\t}\n\n\tif len(branches) == 1 {\n\t\treturn fmt.Sprintf(\"?branch=%s\", branches[0])","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/buildkite/client.go#L45-L81","documentation":"Buildkite's recentBuilds returns the raw HTTP status line (resp.Status, e.g. '401 Unauthorized') as the error whenever the Buildkite API responds outside 2xx. It is a pass-through of the API's status, so the message text is exactly what the server returned.","triggerScenarios":"Any Buildkite REST call in recentBuilds that returns status <200 or >299 — 401 (bad/missing API token), 404 (unknown slug/org), 422 (bad query params), 429/5xx from rate limits or outages.","commonSituations":"Expired or revoked BUILDKITE_TOKEN; wrong organization/pipeline slug in settings; hitting Buildkite rate limits; intermittent Buildkite 5xx incidents.","solutions":["Read the status in the error message and fix the matching cause (401 → token, 404 → slug)","Set/refresh the Buildkite API token with read access to the org and pipelines","Verify organization and pipeline slugs in the widget configuration","Retry with backoff on 429/5xx; check the Buildkite status page"],"exampleFix":"// before\nreq.Header.Set(\"Authorization\", \"Bearer \" + os.Getenv(\"BUILDKITE_TOKEN\")) // unset → 401 Unauthorized\n// after\ntok := os.Getenv(\"BUILDKITE_TOKEN\")\nif tok == \"\" {\n    return nil, errors.New(\"BUILDKITE_TOKEN is not set\")\n}\nreq.Header.Set(\"Authorization\", \"Bearer \" + tok)","handlingStrategy":"try-catch","validationCode":"if os.Getenv(\"BUILDKITE_TOKEN\") == \"\" {\n    return errors.New(\"BUILDKITE_TOKEN must be set\")\n}","typeGuard":null,"tryCatchPattern":"builds, err := client.recentBuilds()\nif err != nil {\n    if strings.Contains(err.Error(), \"429\") || strings.Contains(err.Error(), \"50\") {\n        // transient: retry with backoff\n    } else if strings.Contains(err.Error(), \"401\") {\n        // fix API token\n    }\n    return nil, err\n}","preventionTips":["Check token validity and org/pipeline slugs before deploying config","Implement backoff on 429/5xx statuses","Monitor the Buildkite status page for outages"],"tags":["http","buildkite","api","go"],"backgroundTag":"http-non-2xx-response","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}