Hmbown/CodeWhale · error

bundle fetch failed with HTTP status

Error message

bundle fetch failed with HTTP status {}

What it means

After following any permitted redirects, the bundle fetch completed with a non-success HTTP status. `fetch_bundle` bails with the numeric status so the caller knows the remote refused or could not serve the bundle rather than the request itself failing.

Solutions

  1. Check the URL is correct and the bundle still exists at that location (visit it in a browser or curl -I).
  2. Retry if the server returned 5xx, the outage may be transient.
  3. Download the bundle through an authenticated client manually and import from the local file.

Example fix

// before
codewhale config bundle import https://example.com/bundles/old.zip   # 404
// after
codewhale config bundle import https://example.com/bundles/current.zip
Defensive patterns

Strategy: retry

Try / catch

// retry only on transient 5xx, surface permanent 4xx
match fetch_bundle(url) {
    Err(e) if e.to_string().contains("HTTP status 5") && attempt < 3 => backoff_and_retry(),
    Err(e) => return Err(anyhow!("bundle download failed: {e:#}")),
    Ok(bytes) => Ok(bytes),
}

Prevention

When it happens

Trigger: `codewhale config bundle import <url>` where the final response status is not 2xx — 404 (URL removed), 403 (auth required), 500 (server error), etc.

Common situations: Stale or mistyped bundle URL; a private bundle endpoint requiring credentials (which this CLI refuses to send via URL); a CDN or server outage.

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/f0779c25262e8e03. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/config_bundles.rs:795

        if redirects >= MAX_REDIRECTS {
            bail!("bundle fetch exceeded the five-redirect limit");
        }
        let location = response
            .headers()
            .get(reqwest::header::LOCATION)
            .ok_or_else(|| anyhow!("bundle redirect is missing a valid Location header"))?
            .to_str()
            .map_err(|_| anyhow!("bundle redirect is missing a valid Location header"))?;
        let next_url = current_url
            .join(location)
            .map_err(|_| anyhow!("bundle redirect Location is invalid"))?;
        validate_bundle_redirect(&initial_scheme, &next_url)?;
        current_url = next_url;
        redirects += 1;
    };

    if !response.status().is_success() {
        bail!(
            "bundle fetch failed with HTTP status {}",
            response.status().as_u16()
        );
    }

    // Read at most MAX_BUNDLE_BYTES + 1 so an oversize body is detected
    // rather than silently truncated.
    let mut buffer = Vec::new();
    let body = response;
    body.take(MAX_BUNDLE_BYTES + 1)
        .read_to_end(&mut buffer)
        .map_err(|_| anyhow!("reading remote bundle failed"))?;
    if buffer.len() as u64 > MAX_BUNDLE_BYTES {
        bail!("remote bundle exceeds the {MAX_BUNDLE_BYTES} byte limit; refused");
    }
    Ok(buffer)
}

View on GitHub (pinned to 73e0f67d83)