{"record":{"id":"ea696c7b9563aeb7","repo":"gastownhall/beads","slug":"github-api-returned-status-d","errorCode":null,"errorMessage":"github api returned status %d","messagePattern":"github api returned status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/bd/doctor/version.go","lineNumber":234,"sourceCode":"\t\tTimeout: 5 * time.Second,\n\t}\n\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Set User-Agent as required by GitHub API\n\treq.Header.Set(\"User-Agent\", \"beads-cli-doctor\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"github api returned status %d\", resp.StatusCode)\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar release struct {\n\t\tTagName string `json:\"tag_name\"`\n\t}\n\n\tif err := json.Unmarshal(body, &release); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Strip 'v' prefix if present\n\tversion := strings.TrimPrefix(release.TagName, \"v\")\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/version.go#L216-L252","documentation":"fetchLatestGitHubRelease queries the GitHub API for the latest release. If the HTTP response status is anything other than 200 OK, it aborts and returns this error with the numeric status code. The library deliberately avoids parsing the body when the API did not return a success response, so callers get a clear signal that the request itself failed.","triggerScenarios":"Calling fetchLatestGitHubRelease (via `bd doctor` version check) when the GitHub API responds with a non-200 status: 403 rate-limit, 404 if the repo moved, 5xx server errors, or network-proxied error pages.","commonSituations":"Hitting GitHub's unauthenticated 60-req/hour rate limit (403 with X-RateLimit-Remaining: 0), running `bd doctor` behind a corporate proxy that returns 407/502, or the repository being renamed/made private (404).","solutions":["Wait for the GitHub API rate limit to reset (check the X-RateLimit-Reset header) or set a GITHUB_TOKEN if supported","Check network/proxy configuration; verify `curl -i https://api.github.com/repos/gastownhall/beads/releases/latest` returns 200","Retry later if the API is returning 5xx; check https://www.githubstatus.com","Run `bd doctor` again once connectivity is restored"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, _ := http.Get(apiURL)\nif resp != nil {\n  defer resp.Body.Close()\n  if resp.StatusCode == http.StatusForbidden && resp.Header.Get(\"X-RateLimit-Remaining\") == \"0\" {\n    // rate-limited: wait for X-RateLimit-Reset before retrying\n  }\n}","typeGuard":null,"tryCatchPattern":"latest, err := fetchLatestGitHubRelease(ctx)\nif err != nil {\n  var statusErr interface{ Unwrap() error }\n  log.Printf(\"version check skipped: %v\", err) // non-fatal for doctor\n}","preventionTips":["Avoid running version checks in tight loops to stay under the 60/hr unauthenticated GitHub limit","Use an authenticated token for GitHub API calls when available","Handle all non-200 codes explicitly rather than assuming 404/403 never happen","Check githubstatus.com before assuming a local problem on 5xx"],"tags":["network","github-api","http-status","doctor"],"backgroundTag":"github-api-non-200","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}