{"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":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/update.rs","lineNumber":1577,"sourceCode":"}\n\n/// Download a URL to bytes.\nfn download_url(url: &str, proxy: Option<&Proxy>) -> Result<Vec<u8>> {\n    download_url_with_timeout(url, proxy, UPDATE_DOWNLOAD_TIMEOUT)\n}\n\nfn download_url_with_timeout(\n    url: &str,\n    proxy: Option<&Proxy>,\n    timeout: Duration,\n) -> Result<Vec<u8>> {\n    let mut last_error = None;\n    for attempt in 1..=UPDATE_HTTP_ATTEMPTS {\n        match download_url_once(url, proxy, timeout) {\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(","sourceCodeStart":1559,"sourceCodeEnd":1595,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/update.rs#L1559-L1595","documentation":"The binary download retry loop throws this error when the artifact download returns a non-success HTTP status that is not retryable, or when retries are exhausted. The message includes the status code and the first bytes of the response body (lossy-decoded) to expose what the server actually returned. The DECLARED AS note shows test code reuses the same string via a helper error type in crates/agent for model-resolution failure assertions, but the throwing site is the updater download path.","triggerScenarios":"download_url_once returns 404 (artifact for this platform/arch missing in the release), 403 (rate limit or private repo), or retries against 5xx/408/429 are exhausted during a self-update binary download.","commonSituations":"Updating on an uncommon platform whose artifact was not published; GitHub rate limiting an unauthenticated update; a CDN edge returning 503 until retries ran out; enterprise proxy stripping the download.","solutions":["Check the HTTP status in the message: 404 means the artifact for your platform is missing — verify the release supports your OS/arch or pick another version.","For 403, add authentication or wait for the rate limit to reset.","Retry after a transient 5xx/429 outage.","Inspect the response body printed in the error — a proxy block page or HTML error page will show there."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight HEAD on the artifact URL\nconst res = await fetch(assetUrl, { method: 'HEAD' });\nif (res.status === 404) console.error('artifact missing for this platform/arch');","typeGuard":null,"tryCatchPattern":"match download(url, proxy, timeout) {\n  Err(e) if e.to_string().contains(\"HTTP 404\") => {\n    // artifact not published for this platform: report, don't retry\n  }\n  Err(e) if e.to_string().contains(\"HTTP 5\") || e.to_string().contains(\"HTTP 429\") => {\n    // transient: retry with backoff\n  }\n  other => other,\n}","preventionTips":["Confirm the release publishes an artifact for your OS/arch before updating.","Use authenticated requests to avoid 403 rate limits.","Inspect the body excerpt in the error to spot proxy/HTML block pages.","Keep a rollback path: remember the currently installed version before updating."],"tags":["http","download","update","network"],"backgroundTag":"http-error-response","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}