{"record":{"id":"f487944ee026ff3a","repo":"Kuberwastaken/claurst","slug":"failed-to-build-reqwest-client-f48794","errorCode":null,"errorMessage":"failed to build reqwest client","messagePattern":"failed to build reqwest client","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src-rust/crates/api/src/providers/openai_compat.rs","lineNumber":154,"sourceCode":"\n#[derive(Debug, Deserialize)]\nstruct LmStudioInstanceConfig {\n    #[serde(default)]\n    context_length: Option<u32>,\n}\n\nimpl OpenAiCompatProvider {\n    /// Create a new compat provider.  `base_url` should already include any\n    /// path prefix (e.g. `\"https://api.groq.com/openai/v1\"`).\n    pub fn new(\n        id: impl Into<String>,\n        name: impl Into<String>,\n        base_url: impl Into<String>,\n    ) -> Self {\n        let http_client = reqwest::Client::builder()\n            .timeout(crate::request_timeout())\n            .build()\n            .expect(\"failed to build reqwest client\");\n\n        Self {\n            id: ProviderId::new(id),\n            name: name.into(),\n            base_url: base_url.into(),\n            api_key: None,\n            extra_headers: Vec::new(),\n            quirks: ProviderQuirks::default(),\n            http_client,\n        }\n    }\n\n    /// Set an API key that will be sent as `Authorization: Bearer <key>`.\n    pub fn with_api_key(mut self, key: String) -> Self {\n        self.api_key = if key.is_empty() { None } else { Some(key) };\n        self\n    }\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/api/src/providers/openai_compat.rs#L136-L172","documentation":"This panic comes from an `.expect()` on `reqwest::Client::builder().build()` while constructing an OpenAI-compatible provider. The reqwest client builder only fails when process-wide initialization fails, typically the TLS backend (rustls or native-tls) cannot be initialized. The library treats this as unrecoverable: without an HTTP client no API calls can ever succeed.","triggerScenarios":"Calling `OpenAiCompatProvider::new(id, name, base_url)` in a process where the TLS backend failed to initialize — most commonly `reqwest::Client::builder().timeout(crate::request_timeout()).build()` returning Err because the native TLS library could not be loaded or rustls ring crypto init failed.","commonSituations":"Deploying to a musl/statically-linked or minimal Docker image missing CA certificates or the native TLS shared library; cross-compiled binaries with a mismatched OpenSSL; running in an environment where the crypto provider was already set up differently elsewhere in the process.","solutions":["Check that the binary links a working TLS backend: verify `openssl`/`libssl` is present (`ldd ./claurst`) or switch Cargo features to rustls (`default-features = false, features = [\"rustls-tls\"]` on reqwest).","Add CA certificates to the container image (e.g. `apk add ca-certificates` / `apt-get install ca-certificates`).","If TLS backend init is expected to fail in embedded contexts, refactor `new` to return `Result<Self, reqwest::Error>` and propagate instead of expecting.","Test client construction early at startup (`reqwest::Client::new()`) so the failure surfaces with a clear message rather than deep inside provider setup."],"exampleFix":"// before\nlet http_client = reqwest::Client::builder()\n    .timeout(crate::request_timeout())\n    .build()\n    .expect(\"failed to build reqwest client\");\n// after\nlet http_client = reqwest::Client::builder()\n    .timeout(crate::request_timeout())\n    .build()\n    .map_err(|e| ProviderError::Init(format!(\"failed to build reqwest client: {e}\")))?;","handlingStrategy":"fallback","validationCode":"// Before constructing the provider, probe client construction:\nif let Err(e) = reqwest::Client::new() {\n    eprintln!(\"TLS/HTTP client unavailable: {e}\");\n    // fall back to non-TLS transport or abort startup with a clear message\n}","typeGuard":null,"tryCatchPattern":"// This is a panic, not a Result — catch at process boundary if embedding:\nlet result = std::panic::catch_unwind(|| OpenAiCompatProvider::new(\"id\", \"name\", \"https://api.example.com\"));\nmatch result {\n    Ok(provider) => { /* use provider */ }\n    Err(_) => { /* degrade: disable API features, report TLS init failure */ }\n}","preventionTips":["Build with the rustls-tls feature to avoid native OpenSSL linkage problems","Install ca-certificates in all deployment images","Smoke-test reqwest client construction at application startup, not lazily","Run `ldd` on release binaries in a container matching the target environment"],"tags":["rust","reqwest","tls","panic","http-client"],"backgroundTag":"http-client-init-failed","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}