{"record":{"id":"b15a412f58b34306","repo":"tinyhumansai/openhuman","slug":"failed-to-build-http-client-e","errorCode":null,"errorMessage":"failed to build HTTP client: {e}","messagePattern":"failed to build HTTP client: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/api/rest.rs","lineNumber":288,"sourceCode":"        }\n    }\n    // Which product this core is embedded in. Set at the transport level rather\n    // than only on the SDK because `raw_client()` hands this same client to\n    // callers that bypass the SDK entirely (multipart STT upload), and that\n    // traffic needs attributing too.\n    let (name, value) = crate::api::product::product_identity_header();\n    default_headers.insert(name, value);\n\n    // Platform-appropriate TLS backend: Windows → schannel (honors the OS\n    // cert store, required for corporate TLS-inspection proxies); macOS /\n    // Linux → rustls. See [`crate::openhuman::util::tls::tls_client_builder`].\n    crate::openhuman::util::tls::tls_client_builder()\n        .default_headers(default_headers)\n        .http1_only()\n        .timeout(Duration::from_secs(120))\n        .connect_timeout(Duration::from_secs(15))\n        .build()\n        .map_err(|e| anyhow::anyhow!(\"failed to build HTTP client: {e}\"))\n}\n\n/// Normalize the backend envelope while preserving OpenHuman's historical\n/// response shape. In particular, `/auth/me` returns `{success,user}` rather\n/// than `{success,data}`; SDK transport must not expose that envelope detail to\n/// existing callers.\nfn parse_api_response_value(value: Value) -> Result<Value> {\n    let Some(object) = value.as_object() else {\n        return Ok(value);\n    };\n    if let Some(user) = object.get(\"user\").filter(|user| !user.is_null()) {\n        return Ok(user.clone());\n    }\n    let Some(success) = object.get(\"success\").and_then(Value::as_bool) else {\n        return Ok(value);\n    };\n    if !success {\n        let message = object","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/api/rest.rs#L270-L306","documentation":"Building the shared backend reqwest Client (platform TLS via tls_client_builder — schannel on Windows, rustls elsewhere — plus http1_only, 120s/15s timeouts, and default headers including x-sdk-name) failed. Client construction rarely fails: the realistic causes are TLS backend initialization errors or invalid proxy configuration picked up from the environment.","triggerScenarios":"rustls failing to load its roots (bad SSL_CERT_FILE/SSL_CERT_DIR contents on Linux); a malformed HTTP_PROXY/HTTPS_PROXY/ALL_PROXY value reqwest rejects at build time; a Windows cert store schannel cannot open; TLS features compiled in inconsistently for the target.","commonSituations":"Corporate proxy env vars with unsupported URI syntax set in the shell/service unit; a pinned CA bundle path that no longer exists; cross-compiled binaries missing the right TLS feature; CI images injecting odd proxy vars.","solutions":["Audit proxy env vars first (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY, lowercase variants) — unset them to test whether the build succeeds","Check SSL_CERT_FILE/SSL_CERT_DIR point at a readable PEM bundle if set","Reproduce minimally: build a tiny reqwest client with the same tls_client_builder to isolate TLS vs proxy causes","Ensure the TLS feature set compiled into the binary matches the deployment platform"],"exampleFix":"# before\n export ALL_PROXY='socks'      # malformed → 'failed to build HTTP client' at startup\n# after\n export ALL_PROXY='socks5://127.0.0.1:1080'","handlingStrategy":"validation","validationCode":"fn proxy_env_sane() -> bool {\n    [\"HTTP_PROXY\", \"HTTPS_PROXY\", \"ALL_PROXY\", \"http_proxy\", \"https_proxy\", \"all_proxy\"]\n        .iter()\n        .all(|k| std::env::var(k).map(|v| reqwest::Proxy::all(&v).is_ok()).unwrap_or(true))\n}\nassert!(proxy_env_sane(), \"proxy env contains an unparseable URL\");","typeGuard":null,"tryCatchPattern":"let client = match build_backend_client() {\n    Ok(c) => c,\n    Err(e) => {\n        log::error!(\"backend client build failed ({e}); check proxy/TLS env — names: HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, SSL_CERT_FILE\");\n        return Err(e);\n    }\n};","preventionTips":["validate proxy URLs at config-load time, not first request","run a startup smoke test that builds the client in the deployment environment","fail fast at boot with env var names echoed (names only, never values)"],"tags":["http","tls","reqwest","configuration","startup"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}