Hmbown/CodeWhale · error

download failed with HTTP

Error message

download failed with HTTP {status}: {body}

What it means

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.

Solutions

  1. 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.
  2. For 403, add authentication or wait for the rate limit to reset.
  3. Retry after a transient 5xx/429 outage.
  4. Inspect the response body printed in the error — a proxy block page or HTML error page will show there.
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight HEAD on the artifact URL
const res = await fetch(assetUrl, { method: 'HEAD' });
if (res.status === 404) console.error('artifact missing for this platform/arch');

Try / catch

match download(url, proxy, timeout) {
  Err(e) if e.to_string().contains("HTTP 404") => {
    // artifact not published for this platform: report, don't retry
  }
  Err(e) if e.to_string().contains("HTTP 5") || e.to_string().contains("HTTP 429") => {
    // transient: retry with backoff
  }
  other => other,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/e1b22e6bd2f5a7d2. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/update.rs:1577

}

/// Download a URL to bytes.
fn download_url(url: &str, proxy: Option<&Proxy>) -> Result<Vec<u8>> {
    download_url_with_timeout(url, proxy, UPDATE_DOWNLOAD_TIMEOUT)
}

fn download_url_with_timeout(
    url: &str,
    proxy: Option<&Proxy>,
    timeout: Duration,
) -> Result<Vec<u8>> {
    let mut last_error = None;
    for attempt in 1..=UPDATE_HTTP_ATTEMPTS {
        match download_url_once(url, proxy, timeout) {
            Ok((status, bytes)) if status.is_success() => return Ok(bytes),
            Ok((status, bytes)) => {
                let body = String::from_utf8_lossy(&bytes);
                let error = anyhow!("download failed with HTTP {status}: {body}");
                if should_retry_http_status(status) && attempt < UPDATE_HTTP_ATTEMPTS {
                    last_error = Some(error);
                    sleep_before_update_retry(attempt);
                    continue;
                }
                return Err(error);
            }
            Err(error) if attempt < UPDATE_HTTP_ATTEMPTS => {
                last_error = Some(error);
                sleep_before_update_retry(attempt);
            }
            Err(error) => return Err(error),
        }
    }
    Err(last_error.unwrap_or_else(|| anyhow!("failed to download {url}")))
}

fn download_url_once(

View on GitHub (pinned to 73e0f67d83)