{"record":{"id":"0cc28bcf63522084","repo":"davila7/claude-code-templates","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":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli-rust/src/github.rs","lineNumber":22,"sourceCode":"use crate::constants;\nuse anyhow::{anyhow, Result};\nuse serde_json::Value;\nuse std::time::Duration;\n\n/// Outcome of a raw fetch: found content, an explicit 404, or another HTTP\n/// status (treated as an error by callers).\npub enum Fetched {\n    Ok(String),\n    NotFound,\n    Status(u16),\n}\n\nfn client() -> Result<reqwest::blocking::Client> {\n    reqwest::blocking::Client::builder()\n        .timeout(Duration::from_secs(30))\n        .user_agent(constants::user_agent())\n        .build()\n        .map_err(|e| anyhow!(\"failed to build HTTP client: {e}\"))\n}\n\n/// Fetch a raw URL, distinguishing 404 from other failures so callers can show\n/// the same \"not found\" messaging the Node CLI does.\npub fn fetch_raw(url: &str) -> Result<Fetched> {\n    let resp = client()?.get(url).send()?;\n    let status = resp.status();\n    if status.is_success() {\n        Ok(Fetched::Ok(resp.text()?))\n    } else if status.as_u16() == 404 {\n        Ok(Fetched::NotFound)\n    } else {\n        Ok(Fetched::Status(status.as_u16()))\n    }\n}\n\n/// Fetch a raw URL, returning `Some(text)` only on 2xx (used for optional\n/// sidecar files like `.py`/`.sh` where any failure is silently ignored).","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-rust/src/github.rs#L4-L40","documentation":"The Rust helper `client()` in cli-rust/src/github.rs failed to construct a reqwest blocking Client. reqwest's builder returns Err when TLS backend initialization fails or builder options (timeout, user_agent) are invalid. The anyhow! wrapper attaches 'failed to build HTTP client' with the underlying error string.","triggerScenarios":"Calling github::fetch_raw, fetch_raw_optional, or walk (e.g. via download_skill_tree) on a machine where the native TLS root store cannot be loaded (missing ca-certificates), or when reqwest was compiled without a TLS feature, or an invalid User-Agent header value from constants::user_agent().","commonSituations":"Fresh Linux container/alpine image without ca-certificates installed; building with default-features=false on reqwest; broken SSL environment variables; static binary in a minimal Docker image.","solutions":["Ensure the system has CA certificates (apt install ca-certificates / apk add ca-certificates) and retry","Check reqwest Cargo features include a TLS backend (e.g. features = [\"blocking\", \"default-tls\"] or rustls-tls)","Print the underlying error: run with RUST_LOG=debug or inspect {e} to see if it's TLS, DNS, or header related","Verify constants::user_agent() returns a valid header value (no newlines/invalid chars)"],"exampleFix":"// Cargo.toml — before\nreqwest = { version = \"0.12\", features = [\"blocking\", \"json\"] }\n// after (explicit TLS backend)\nreqwest = { version = \"0.12\", default-features = false, features = [\"blocking\", \"json\", \"rustls-tls\"] }","handlingStrategy":"fallback","validationCode":"// Before first use, verify a client can be built once and reuse it\nuse once_cell::sync::Lazy;\nstatic CLIENT: Lazy<Result<reqwest::blocking::Client>> =\n    Lazy::new(|| reqwest::blocking::Client::builder()\n        .timeout(Duration::from_secs(30))\n        .user_agent(constants::user_agent())\n        .build());\n\nfn ensure_client() -> Result<&'static reqwest::blocking::Client> {\n    CLIENT.as_ref().map_err(|e| anyhow!(\"failed to build HTTP client: {e}\"))\n}","typeGuard":null,"tryCatchPattern":"// catch at the command boundary and surface a TLS/env hint\nmatch github::fetch_raw(url) {\n    Err(e) if e.to_string().contains(\"failed to build HTTP client\") => {\n        eprintln!(\"{e}\\nHint: check that CA certificates are installed and reqwest has a TLS feature enabled\");\n        std::process::exit(2);\n    }\n    other => other,\n}","preventionTips":["Pin an explicit TLS feature (rustls-tls) so builds never lack a backend","Include ca-certificates in Docker images that run the CLI","Fail fast: build the shared client once at startup, not per request"],"tags":["rust","reqwest","tls","http-client","network"],"backgroundTag":"tls-initialization-failed","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}