Hmbown/CodeWhale · error

failed to build HTTP client

Error message

failed to build HTTP client

What it means

Panic constructing the finance tool's HTTP client: `crate::tls::reqwest_client_builder()` with a user agent fails at `.build()`. Same family as the skills installer's client-build panic: TLS backend initialization failure (bad `SSL_CERT_FILE`/`SSL_CERT_DIR`, unreadable CA store, broken OpenSSL) or conflicting builder settings. `FinanceTool::new()` runs when the tool is registered, so the panic can abort turn/tool setup rather than just one web call.

Source

Thrown at crates/tui/src/tools/finance.rs:159

    fn summary(&self) -> String {
        format!("{}: {}", self.endpoint, self.detail)
    }
}

pub struct FinanceTool {
    endpoints: FinanceEndpoints,
    client: Client,
}

impl FinanceTool {
    #[must_use]
    pub fn new() -> Self {
        Self {
            endpoints: FinanceEndpoints::default(),
            client: crate::tls::reqwest_client_builder()
                .user_agent(USER_AGENT)
                .build()
                .expect("failed to build HTTP client"),
        }
    }

    #[cfg(test)]
    fn with_endpoints(quote_base: impl Into<String>, chart_base: impl Into<String>) -> Self {
        Self {
            endpoints: FinanceEndpoints {
                quote_base: quote_base.into(),
                chart_base: chart_base.into(),
            },
            client: crate::tls::reqwest_client_builder()
                .user_agent(USER_AGENT)
                .build()
                .expect("failed to build HTTP client"),
        }
    }
}

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Check `env | grep -iE 'ssl|proxy'`; make `SSL_CERT_FILE`/`SSL_CERT_DIR` point at existing readable bundles or unset them.
  2. Reinstall the system CA package and retry.
  3. Verify with `RUST_BACKTRACE=1` that the failure is in the client builder, then report the platform TLS configuration.
  4. For embedders: build the client lazily per call and surface `reqwest::Error` instead of panicking in `new()`.

Example fix

// before
client: crate::tls::reqwest_client_builder()
    .user_agent(USER_AGENT)
    .build()
    .expect("failed to build HTTP client")

// after: log the TLS misconfiguration and fall back to a default client
let client = crate::tls::reqwest_client_builder()
    .user_agent(USER_AGENT)
    .build()
    .unwrap_or_else(|err| {
        tracing::warn!("custom TLS client build failed: {err}; using default client");
        reqwest::Client::new()
    });
Defensive patterns

Strategy: validation

Validate before calling

// Verify the TLS trust environment before registering the finance tool
for var in ["SSL_CERT_FILE", "SSL_CERT_DIR"] {
    if let Ok(v) = std::env::var(var) {
        assert!(std::path::Path::new(&v).exists(), "{var}={v} does not exist");
    }
}

Try / catch

let client = std::panic::catch_unwind(|| {
    crate::tls::reqwest_client_builder().user_agent(USER_AGENT).build()
})
.map(std::result::Result::unwrap)
.unwrap_or_else(|_| reqwest::Client::new());

Prevention

When it happens

Trigger: A machine whose TLS trust environment is broken (env vars pointing at missing files, empty `/etc/ssl/certs`); the first turn that instantiates the finance tool panics inside `new()`.

Common situations: Hardened shells and Nix/direnv setups leaking `SSL_*` vars; minimal CI/dev containers without `ca-certificates`; hosts behind TLS-intercepting proxies with roots outside the default store.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/f50bd2c57486de9c. Report an issue: GitHub.