{"record":{"id":"4e9b0343b32b8d61","repo":"Hmbown/CodeWhale","slug":"ds4-v1-models-could-not-be-reached-at-is-ds4","errorCode":null,"errorMessage":"DS4 /v1/models could not be reached at {} (is ds4-server running?)","messagePattern":"DS4 /v1/models could not be reached at (.+?) \\(is ds4-server running\\?\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/doctor.rs","lineNumber":583,"sourceCode":"}\n\n/// Probe DS4 through its cheap `/v1/models` contract instead of waking the\n/// model for a completion. The selected model must be advertised.\npub(crate) async fn probe_ds4_models(config: &crate::config::Config) -> anyhow::Result<()> {\n    use crate::client::DeepSeekClient;\n    use crate::core::model_client::ModelClient;\n\n    let endpoint = crate::client::redact_url_for_display(&config.deepseek_base_url());\n    let client = DeepSeekClient::new(config)?;\n    let configured_alias = client.model().to_string();\n    let models = match tokio::time::timeout(\n        std::time::Duration::from_secs(15),\n        client.list_models(),\n    )\n    .await\n    {\n        Ok(Ok(models)) => models,\n        Ok(Err(error)) => anyhow::bail!(ds4_probe_error(config, &error.to_string())),\n        Err(_) => anyhow::bail!(\"DS4 /v1/models timed out after 15 seconds at {}\", endpoint),\n    };\n    if !models\n        .iter()\n        .any(|available| available.id == configured_alias)\n    {\n        let advertised = models\n            .iter()\n            .take(8)\n            .map(|available| available.id.as_str())\n            .collect::<Vec<_>>()\n            .join(\", \");\n        anyhow::bail!(\n            \"DS4 /v1/models at {} did not list configured alias '{configured_alias}' (advertised: {})\",\n            endpoint,\n            if advertised.is_empty() {\n                \"none\"\n            } else {","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/doctor.rs#L565-L601","documentation":"Produced by ds4_probe_error during doctor's probe_ds4_models: list_models failed with a connection-level error that contains no HTTP status token — the request never got an HTTP response. The message explicitly asks whether ds4-server is running and prints the redacted endpoint.","triggerScenarios":"Nothing listening on the configured host:port (connection refused), DNS resolution failure for the base URL host, or a TLS handshake failure on an https base URL.","commonSituations":"ds4-server not started or crashed; wrong port in deepseek_base_url; firewall or VPN blocking localhost/remote endpoints; https pointed at an http listener.","solutions":["Start ds4-server and confirm it listens on the configured host and port","Verify deepseek_base_url (scheme, host, port) matches the server's actual bind address","Test reachability directly, e.g. curl the /v1/models URL from the same machine"],"exampleFix":"# before\ndeepseek_base_url = \"http://127.0.0.1:9000\"\n\n# after (server listens on 8080)\ndeepseek_base_url = \"http://127.0.0.1:8080\"","handlingStrategy":"retry","validationCode":"// Cheap pre-check that something is listening before the probe:\nlet url = config.deepseek_base_url();\nlet host_port = parse_host_port(&url)?;\nif !tcp_connectable(host_port, std::time::Duration::from_secs(1)).await {\n    return Err(anyhow::anyhow!(\"ds4 endpoint {host_port} is not accepting connections; start ds4-server\"));\n}","typeGuard":null,"tryCatchPattern":"match probe_ds4_models(&config).await {\n    Ok(()) => {}\n    Err(error) if error.to_string().contains(\"could not be reached\") => {\n        // start ds4-server (or fix the URL), then retry the probe once\n    }\n    Err(error) => return Err(error),\n}","preventionTips":["Start ds4-server before running doctor and verify the port matches deepseek_base_url","Prefer a loopback base URL for local servers to avoid firewall/DNS surprises","Keep one canonical base URL in config instead of per-tool copies that drift"],"tags":["rust","tui","network","ds4","doctor","connection-refused"],"backgroundTag":"connection-refused","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}