{"record":{"id":"265694310f169e9b","repo":"chenhg5/cc-connect","slug":"github-api-returned-http-d","errorCode":null,"errorMessage":"GitHub API returned HTTP %d","messagePattern":"GitHub API returned HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/update.go","lineNumber":229,"sourceCode":"\t\treturn fetchLatestPreRelease()\n\t}\n\treturn fetchLatestStableRelease()\n}\n\n// fetchLatestPreRelease fetches the newest release (including pre-releases) from GitHub.\nfunc fetchLatestPreRelease() (*githubRelease, error) {\n\tclient := &http.Client{Timeout: 15 * time.Second}\n\treq, _ := http.NewRequest(\"GET\", githubAllAPI+\"?per_page=10\", nil)\n\treq.Header.Set(\"Accept\", \"application/vnd.github.v3+json\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"request failed: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"GitHub API returned HTTP %d\", resp.StatusCode)\n\t}\n\n\tvar releases []githubRelease\n\tif err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse releases: %w\", err)\n\t}\n\n\tif len(releases) == 0 {\n\t\treturn nil, fmt.Errorf(\"no releases found\")\n\t}\n\n\t// Return the first (newest) release, which may be a pre-release\n\treturn &releases[0], nil\n}\n\n// fetchLatestStableRelease fetches the latest stable release (no pre-releases).\nfunc fetchLatestStableRelease() (*githubRelease, error) {\n\tclient := &http.Client{Timeout: 15 * time.Second}","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/update.go#L211-L247","documentation":"fetchLatestPreRelease returns this when the GitHub releases API responds with a status code other than 200. The code is embedded in the message so the developer can see exactly what GitHub returned (403 rate limit, 404 wrong repo, 5xx outage, etc.).","triggerScenarios":"The GET to githubAllAPI+\"?per_page=10\" succeeds at transport level but resp.StatusCode != 200: GitHub API rate limiting (HTTP 403, X-RateLimit-Remaining: 0), wrong repo slug producing 404, GitHub 5xx incidents, or an intercepting proxy returning an error page.","commonSituations":"Unauthenticated GitHub API calls from shared/CI IPs exhausting the 60 req/hour rate limit; typo in the repo slug baked into githubAllAPI; GitHub status incidents; captive portals or corporate middleware returning non-200.","solutions":["Read the exact HTTP code in the message; for 403 check X-RateLimit-Remaining — if 0, wait for reset or authenticate with a GITHUB_TOKEN header","Verify githubAllAPI points at the correct repo (curl it directly and inspect the response)","Check https://www.githubstatus.com for ongoing GitHub API incidents","If a proxy/captive portal is present, exclude api.github.com or authenticate properly"],"exampleFix":"// before\nreq, _ := http.NewRequest(\"GET\", githubAllAPI+\"?per_page=10\", nil)\n// after\nreq, _ := http.NewRequest(\"GET\", githubAllAPI+\"?per_page=10\", nil)\nif tok := os.Getenv(\"GITHUB_TOKEN\"); tok != \"\" {\n    req.Header.Set(\"Authorization\", \"Bearer \"+tok) // avoids 403 rate limits\n}","handlingStrategy":"fallback","validationCode":"// pre-check rate limit without consuming it:\nreq, _ := http.NewRequest(\"GET\", \"https://api.github.com/rate_limit\", nil)\nresp, err := http.DefaultClient.Do(req)\nif err == nil {\n    var r struct{ Resources struct{ Core struct{ Remaining int } } }\n    json.NewDecoder(resp.Body).Decode(&r)\n    if r.Resources.Core.Remaining == 0 { return errors.New(\"GitHub rate limit exhausted; set GITHUB_TOKEN\") }\n}","typeGuard":null,"tryCatchPattern":"// Go: distinguish status classes\nif _, err := fetchRelease(); err != nil {\n    switch {\n    case strings.Contains(err.Error(), \"HTTP 403\"):\n        // rate limited: back off or authenticate\n    case strings.Contains(err.Error(), \"HTTP 404\"):\n        // wrong repo slug: fix githubAllAPI\n    case strings.Contains(err.Error(), \"HTTP 5\"):\n        // GitHub outage: retry later\n    }\n}","preventionTips":["Authenticate GitHub API calls with a token to raise the rate limit from 60 to 5000/hour","Avoid calling the update check in tight loops or across many CI jobs sharing one IP","Monitor githubstatus.com during deploy windows","Pin and test the repo slug in configuration"],"tags":["http","github-api","rate-limit","update-checker","http-status"],"backgroundTag":"http-error-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}