tinyhumansai/openhuman · error

failed to build Exa HTTP client: {e}

Error message

failed to build Exa HTTP client: {e}

What it means

Returned by ExaClient::http_client() when reqwest's TLS-backed client builder fails (e.g. native TLS backend unavailable or misconfigured). The client is built lazily at call time — deliberately mirroring brave.rs — so that a process-wide TLS construction failure surfaces as a normal tool error on the search call instead of aborting process or session construction. The faulty input is the environment's TLS configuration, not the search arguments.

Source

Thrown at src/openhuman/search/tools/exa.rs:144

        timeout_secs: u64,
    ) -> Self {
        Self {
            api_key,
            api_url: api_url.unwrap_or_else(|| DEFAULT_API_URL.to_string()),
            max_results: max_results.clamp(1, 20),
            timeout_secs: timeout_secs.max(1),
        }
    }

    /// Build the HTTP client at call time, like `brave.rs::http_client`, so a
    /// TLS-backend failure surfaces as a tool error instead of aborting the
    /// process while a session is being constructed.
    fn http_client(&self) -> anyhow::Result<reqwest::Client> {
        crate::openhuman::util::tls::tls_client_builder()
            .timeout(Duration::from_secs(self.timeout_secs))
            .connect_timeout(Duration::from_secs(10))
            .build()
            .map_err(|e| anyhow::anyhow!("failed to build Exa HTTP client: {e}"))
    }

    /// Destination host for the egress descriptor, e.g. `api.exa.ai`.
    fn egress_host(&self) -> String {
        reqwest::Url::parse(&self.api_url)
            .ok()
            .and_then(|u| u.host_str().map(str::to_string))
            .unwrap_or_else(|| "api.exa.ai".to_string())
    }

    /// Egress descriptor for a call to Exa. The query (or the requested URLs)
    /// is user content leaving the device, so it carries `Prompt` on top of the
    /// destination `Url` that `network_fetch` supplies.
    fn egress_descriptor(&self) -> crate::openhuman::security::egress::EgressDescriptor {
        crate::openhuman::security::egress::EgressDescriptor::network_fetch(self.egress_host())
            .with_data_kind(crate::openhuman::security::egress::DataKind::Prompt)
    }

View on GitHub (pinned to 7491200858)

Solutions

  1. Check the platform TLS backend (rustls vs native-tls) and ensure required root certificates are present.
  2. Verify no proxy or security software corrupts certificate loading; inspect OPENHUMAN TLS/env settings.
  3. Fix util::tls::tls_client_builder configuration and retry the search call.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/openhuman/search/tools/exa.rs:144 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/bc5f128c41a482cf. Report an issue: GitHub.