Hmbown/CodeWhale · error · anyhow::Error

download failed with HTTP {status}: {body}

Error message

download failed with HTTP {status}: {body}

What it means

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.

Source

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

    let releases: Vec<Release> = serde_json::from_str(&body).with_context(|| {
        format!("failed to parse release list JSON from GitHub API. Response: {body}")
    })?;

    releases
        .into_iter()
        .find(|release| is_beta_tag(&release.tag_name))
        .context("no beta release found in GitHub releases")
}

/// Download a URL to bytes.
fn download_url(url: &str, proxy: Option<&Proxy>) -> Result<Vec<u8>> {
    let mut last_error = None;
    for attempt in 1..=UPDATE_HTTP_ATTEMPTS {
        match download_url_once(url, proxy) {
            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(url: &str, proxy: Option<&Proxy>) -> Result<(reqwest::StatusCode, Vec<u8>)> {

View on GitHub (pinned to 8880682c63)

Solutions

  1. Re-run the update check to refresh release metadata before downloading; a 404 usually means the cached asset URL is stale
  2. If 403/4xx came from a proxy page, read the body text, then configure Codewhale's proxy setting or download outside the intercepting network
  3. For 5xx, retry later; the code already did 3 attempts with 100ms*attempt backoff
  4. As a last resort, download the release artifact manually and install it

Example fix

# before
$ codewhale update   # download failed with HTTP 404: stale asset URL

# after: refresh metadata, then update again
$ codewhale update check && codewhale update
Defensive patterns

Strategy: retry

Try / catch

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).

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/e1b22e6bd2f5a7d2. Report an issue: GitHub.