Hmbown/CodeWhale · error

building bundle fetch client failed

Error message

building bundle fetch client failed

What it means

`fetch_bundle` builds its HTTP client via `platform_blocking_http_client_builder` with a timeout and `Policy::none()` redirects; if `reqwest::Client::build()` fails, this error is raised before any request is made. It indicates the HTTP client could not be constructed in this environment.

Solutions

  1. Ensure the system CA certificate bundle exists (e.g. install `ca-certificates` or set SSL_CERT_FILE/SSL_CERT_DIR).
  2. Reinstall/upgrade the `codewhale` binary for your platform; the TLS backend may be broken in that build.
  3. Check that no environment overriding cert paths points to a nonexistent file.
Defensive patterns

Strategy: try-catch

Validate before calling

// heuristic pre-check: a missing CA bundle usually breaks client build
if !std::path::Path::new("/etc/ssl/certs/ca-certificates.crt").exists()
    && std::env::var_os("SSL_CERT_FILE").is_none() {
    eprintln!("no system CA bundle found; TLS client build will likely fail");
}

Try / catch

match fetch_bundle(url) {
    Err(e) if e.to_string().contains("building bundle fetch client failed") => {
        eprintln!("check TLS/CA setup: install ca-certificates or set SSL_CERT_FILE");
    }
    other => other,
}

Prevention

When it happens

Trigger: `reqwest::ClientBuilder::build()` fails inside `fetch_bundle` — typically TLS backend initialization failure (no system roots, broken OpenSSL/rustls setup) or unavailable runtime resources.

Common situations: Missing/empty system CA certificate store (minimal containers, musl builds without roots); mismatched OpenSSL versions at runtime; statically linked builds lacking TLS roots.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

// ---------------------------------------------------------------------------
// Remote fetch
// ---------------------------------------------------------------------------

/// Fetch a bundle over HTTPS (or plain http on loopback only) with a hard
/// size cap, a timeout, and bounded redirects. Mirrors the skill installer's
/// fetch bounds.
pub fn fetch_bundle(url: &str) -> Result<Vec<u8>> {
    let mut current_url = reqwest::Url::parse(url).map_err(|_| anyhow!("invalid bundle URL"))?;
    validate_bundle_url(&current_url)?;
    let initial_scheme = current_url.scheme().to_string();

    let client = codewhale_release::platform_blocking_http_client_builder()
        .timeout(std::time::Duration::from_secs(FETCH_TIMEOUT_SECS))
        // Redirect targets must pass the same scheme/host policy as the
        // initial request, so redirects are followed explicitly below.
        .redirect(reqwest::redirect::Policy::none())
        .build()
        .map_err(|_| anyhow!("building bundle fetch client failed"))?;
    let mut redirects = 0usize;
    let response = loop {
        let response = client
            .get(current_url.clone())
            .send()
            // reqwest errors can include the full URL (including its query or
            // userinfo), so keep transport failures deliberately URL-free.
            .map_err(|_| anyhow!("bundle fetch request failed"))?;

        if !response.status().is_redirection() {
            break response;
        }
        if redirects >= MAX_REDIRECTS {
            bail!("bundle fetch exceeded the five-redirect limit");
        }
        let location = response
            .headers()
            .get(reqwest::header::LOCATION)

View on GitHub (pinned to 73e0f67d83)