{"record":{"id":"e9b753457e085f33","repo":"chenhg5/cc-connect","slug":"http-d-for-s","errorCode":null,"errorMessage":"HTTP %d for %s","messagePattern":"HTTP (.+?) for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/updater.go","lineNumber":195,"sourceCode":"\t\t\t\treturn fmt.Errorf(\"too many redirects\")\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"User-Agent\", \"cc-connect-updater\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"HTTP %d for %s\", resp.StatusCode, url)\n\t}\n\n\treturn io.ReadAll(resp.Body)\n}\n\nfunc extractBinaryFromTarGz(data []byte) ([]byte, error) {\n\tr := bytes.NewReader(data)\n\tgr, err := gzip.NewReader(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer gr.Close()\n\n\ttr := tar.NewReader(gr)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/updater.go#L177-L213","documentation":"downloadFile in the self-updater fails closed on any HTTP status other than 200 OK: it reads the body only after this check, so a non-OK response yields this wrapped error carrying the status code and the URL instead of update bytes. It exists so callers see the real status (e.g. 404, 403, 503) rather than a confusing 'unexpected end of JSON' or empty-archive error downstream.","triggerScenarios":"SelfUpdate -> downloadFile fetched the release asset URL and the server responded with any status != 200: release asset renamed or deleted, tag missing, download URL typo, GitHub rate limiting/502, proxy returning an error page, private repo asset without a token.","commonSituations":"Running an old version whose hardcoded download URL no longer resolves (404); corporate proxy intercepting the download with a 403 page; GitHub API rate limit for unauthenticated requests (403 with rate-limit headers); transient CDN errors (502/503); mirroring the binary under a changed asset naming scheme.","solutions":["Check the status code in the error and fetch the URL with curl -I to see the actual response; fix the download URL or asset name it points to.","If it's 403 from GitHub, wait for the rate-limit window or authenticate (GITHUB_TOKEN) and retry.","Retry the update later if the status is 5xx — it is usually a transient server/CDN problem.","Verify the release exists for your platform (asset names differ per OS/arch) and upgrade in two steps if the current version points to a dead URL.","As a last resort, download and replace the binary manually using the same layout the updater expects (tar.gz or zip containing a cc-connect* file)."],"exampleFix":"// before\nresp, err := http.Get(url) // url points to v0.9 asset that was replaced\n...\n// HTTP 404 for https://.../cc-connect-v0.9-linux-amd64.tar.gz\n// after\n# fix the asset URL for the new release\nresp, err := http.Get(\"https://github.com/org/cc-connect/releases/latest/download/cc-connect-linux-amd64.tar.gz\")","handlingStrategy":"retry","validationCode":"resp, err := http.Head(url)\nif err != nil || resp.StatusCode != http.StatusOK {\n    return fmt.Errorf(\"download URL not ready: status=%v err=%v\", resp.StatusCode, err)\n}","typeGuard":null,"tryCatchPattern":"if err := selfUpdate(); err != nil {\n    var he *StatusError\n    if errors.As(err, &he) && he.Code >= 500 {\n        // transient: retry with backoff\n    } else if errors.As(err, &he) && he.Code == 403 {\n        // rate limited: wait for Reset-After\n    }\n}","preventionTips":["Ping the release URL with curl -I before running self-update","Pin to a 'latest' asset URL that the release pipeline keeps valid","Authenticate GitHub requests to avoid 403 rate limits","Check github.com rate-limit headers when updating from CI"],"tags":["http","network","self-update"],"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"}