Hmbown/CodeWhale · error

bundle redirect is missing a valid Location header

Error message

bundle redirect is missing a valid Location header

What it means

During redirect handling in fetch_bundle, the server responded with a redirection status but sent no Location header at all. The client requires a Location header to know where to follow; a redirect without one is unusable, so it fails with this message. This is treated as an invalid server response rather than retrying.

Solutions

  1. Fix the server/proxy to include a Location header on redirect responses.
  2. Fetch the final bundle URL directly instead of relying on the redirect.
  3. Check for middleware or CDN rewriting the response and stripping Location.
  4. Inspect the raw response with curl -i to confirm the malformed redirect.

Example fix

// before (server)
HTTP/1.1 302 Found

// after (server)
HTTP/1.1 302 Found
Location: https://host/bundle.toml
Defensive patterns

Strategy: fallback

Validate before calling

let resp = client.get(url).send()?; if resp.status().is_redirection() && resp.headers().get(header::LOCATION).is_none() { eprintln!("malformed redirect from {}", host); }

Try / catch

if let Err(e) = fetch_bundle(url) { if e.to_string().contains("missing a valid Location") { eprintln!("server sent redirect without Location; use direct URL"); } }

Prevention

When it happens

Trigger: A 3xx response with no Location header (or a Location header containing non-ASCII/invalid bytes that fail to_str) while fetching a config bundle URL.

Common situations: Misconfigured reverse proxies emitting bare 302s, custom servers that redirect without Location, broken redirector scripts on bundle mirrors.

Related errors


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

Appendix: source

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

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

View on GitHub (pinned to 73e0f67d83)