{"record":{"id":"7876325f1d9326cf","repo":"Hmbown/CodeWhale","slug":"request-timeout-after-15-seconds","errorCode":null,"errorMessage":"Request timeout after 15 seconds","messagePattern":"Request timeout after 15 seconds","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":7456,"sourceCode":"        max_tokens: 1,\n        system: None,\n        tools: None,\n        tool_choice: None,\n        metadata: None,\n        thinking: None,\n        // This is a one-token transport probe, not a reasoning task.\n        reasoning_effort: Some(\"off\".to_string()),\n        stream: Some(false),\n        temperature: None,\n        top_p: None,\n    };\n\n    // Use tokio timeout to catch hanging requests\n    let timeout_duration = std::time::Duration::from_secs(15);\n    match tokio::time::timeout(timeout_duration, client.create_message(request)).await {\n        Ok(Ok(_response)) => Ok(()),\n        Ok(Err(e)) => Err(e),\n        Err(_) => anyhow::bail!(\"Request timeout after 15 seconds\"),\n    }\n}\n\nfn rustc_version() -> String {\n    let Some(mut cmd) = crate::dependencies::RustC::command() else {\n        return \"unknown\".to_string();\n    };\n    let Ok(output) = cmd.arg(\"--version\").output() else {\n        return \"unknown\".to_string();\n    };\n    String::from_utf8(output.stdout)\n        .map(|s| s.trim().to_string())\n        .unwrap_or_else(|_| \"unknown\".to_string())\n}\n\n/// List saved sessions\nfn sessions_resume_command() -> &'static str {\n    \"codewhale resume\"","sourceCodeStart":7438,"sourceCodeEnd":7474,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/lib.rs#L7438-L7474","documentation":"test_api_connectivity sends a one-token, non-streaming 'hi' request through the configured provider and wraps it in tokio::time::timeout(15s). If the request neither completes nor errors within 15 seconds — it hangs — you get 'Request timeout after 15 seconds'. Real API errors (auth, HTTP 4xx/5xx, DNS failure) take the Ok(Err(e)) arm and surface their own message; only a silent hang produces this one.","triggerScenarios":"The HTTP request stalls: a firewall silently dropping packets to the API host (connection opened or SYN never answered), HTTP_PROXY/HTTPS_PROXY pointing at a dead proxy, a VPN split-tunnel problem, or an endpoint that accepts the connection but never responds.","commonSituations":"Corporate proxy or VPN misconfiguration; proxy env vars left over in the shell; regional blocking of the API endpoint; DNS resolving to a black-hole address.","solutions":["Verify reachability with the same environment: curl -m 15 <api-base-url> and compare behavior","Check HTTP_PROXY/HTTPS_PROXY/NO_PROXY — unset stale proxies or point them at a live proxy","Adjust or disconnect the VPN so the API host is reachable","Try a different network; if it works elsewhere, a local network policy is the cause","Re-run the doctor/connectivity command — transient middlebox drops often clear"],"exampleFix":"# before: proxy env points at a dead local proxy\nexport HTTPS_PROXY=http://127.0.0.1:8888\ncodewhale doctor\n\n# after\nunset HTTPS_PROXY\ncodewhale doctor","handlingStrategy":"retry","validationCode":"# Pre-flight: does the API base answer within 15s under the same proxy env?\ncurl -sS -o /dev/null -m 15 -w '%{http_code}\\n' \"https://<your-api-base-url>\"","typeGuard":null,"tryCatchPattern":"for attempt in 1..=2u32 {\n    match tokio::time::timeout(std::time::Duration::from_secs(15), client.create_message(req())).await {\n        Ok(Ok(_)) => return Ok(()),\n        Ok(Err(e)) => return Err(e),               // real API error: do not blind-retry\n        Err(_) if attempt < 2 => continue,          // hang: retry once\n        Err(_) => anyhow::bail!(\"Request timeout after 15 seconds\"),\n    }\n}","preventionTips":["Pre-flight the API base with curl -m 15 in the same shell before launching","Keep HTTP_PROXY/HTTPS_PROXY/NO_PROXY correct or unset","Treat a hang differently from an API error — only the hang timeout benefits from retry"],"tags":["rust","network","timeout","api","proxy","diagnostics"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}