{"record":{"id":"e1b22e6bd2f5a7d2","repo":"Hmbown/CodeWhale","slug":"download-failed-with-http-status-body","errorCode":null,"errorMessage":"download failed with HTTP {status}: {body}","messagePattern":"download failed with HTTP (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/update.rs","lineNumber":1125,"sourceCode":"    let releases: Vec<Release> = serde_json::from_str(&body).with_context(|| {\n        format!(\"failed to parse release list JSON from GitHub API. Response: {body}\")\n    })?;\n\n    releases\n        .into_iter()\n        .find(|release| is_beta_tag(&release.tag_name))\n        .context(\"no beta release found in GitHub releases\")\n}\n\n/// Download a URL to bytes.\nfn download_url(url: &str, proxy: Option<&Proxy>) -> Result<Vec<u8>> {\n    let mut last_error = None;\n    for attempt in 1..=UPDATE_HTTP_ATTEMPTS {\n        match download_url_once(url, proxy) {\n            Ok((status, bytes)) if status.is_success() => return Ok(bytes),\n            Ok((status, bytes)) => {\n                let body = String::from_utf8_lossy(&bytes);\n                let error = anyhow!(\"download failed with HTTP {status}: {body}\");\n                if should_retry_http_status(status) && attempt < UPDATE_HTTP_ATTEMPTS {\n                    last_error = Some(error);\n                    sleep_before_update_retry(attempt);\n                    continue;\n                }\n                return Err(error);\n            }\n            Err(error) if attempt < UPDATE_HTTP_ATTEMPTS => {\n                last_error = Some(error);\n                sleep_before_update_retry(attempt);\n            }\n            Err(error) => return Err(error),\n        }\n    }\n    Err(last_error.unwrap_or_else(|| anyhow!(\"failed to download {url}\")))\n}\n\nfn download_url_once(url: &str, proxy: Option<&Proxy>) -> Result<(reqwest::StatusCode, Vec<u8>)> {","sourceCodeStart":1107,"sourceCodeEnd":1143,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/cli/src/update.rs#L1107-L1143","documentation":"download_url fetches a release asset (binary download) and received a non-success HTTP status; the body is included as lossy UTF-8 diagnostic text. Retryable statuses (5xx, 408, 429) are retried up to 3 times with linear backoff; everything else, such as 404 or 403, fails immediately.","triggerScenarios":"Stale or expired release-asset URL (404), CDN/S3 access denied (403), a proxy or firewall serving a 4xx page for the binary host, or a GitHub/CDN 5xx persisting across all retries.","commonSituations":"Update metadata cached from an earlier run pointing at an asset that was removed or re-uploaded; corporate proxies blocking large binary downloads; transient CDN errors during a GitHub incident.","solutions":["Re-run the update check to refresh release metadata before downloading; a 404 usually means the cached asset URL is stale","If 403/4xx came from a proxy page, read the body text, then configure Codewhale's proxy setting or download outside the intercepting network","For 5xx, retry later; the code already did 3 attempts with 100ms*attempt backoff","As a last resort, download the release artifact manually and install it"],"exampleFix":"# before\n$ codewhale update   # download failed with HTTP 404: stale asset URL\n\n# after: refresh metadata, then update again\n$ codewhale update check && codewhale update","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Extract the status from the message: on 404 refresh update metadata before retrying (stale asset URL); on 5xx retry with capped backoff; on other 4xx inspect the embedded body and stop (proxy or permission problem, not transient).","preventionTips":["Refresh release metadata before downloading when it was cached a long time","Configure the proxy for the binary/CDN host, not just the API host","Fall back to manual download when retries are exhausted"],"tags":["network","http","download","self-update","cdn"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}