Hmbown/CodeWhale · error
DS4 /v1/models returned HTTP
Error message
DS4 /v1/models returned HTTP {status} at {} What it means
`probe_ds4_models` (doctor check) calls the DeepSeek Harness 4 endpoint's `/v1/models` through `client.list_models()`. If the client returns an error (as opposed to timing out), the probe bails with a formatted probe error including the endpoint. This indicates the DS4 endpoint is reachable-configured but rejected or failed the models request.
Solutions
- Run the doctor again and read `ds4_probe_error`'s message, which embeds the underlying client error, then fix that root cause.
- Verify the DS4 endpoint URL and that the server is running (`curl <endpoint>/v1/models`).
- Check that the API key/credentials for DS4 are set and valid.
- If TLS-related, fix or trust the endpoint's certificate chain.
Defensive patterns
Strategy: validation
Validate before calling
// before running the doctor probe, check the endpoint yourself curl -sS --max-time 10 -H "Authorization: Bearer $DS4_KEY" "$DS4_ENDPOINT/v1/models" | head -c 200
Try / catch
match doctor_probe().await {
Err(e) if e.to_string().contains("DS4 /v1/models") && !e.to_string().contains("timed out") => {
// read embedded ds4_probe_error text and fix endpoint/key/TLS
}
other => other?,
} Prevention
- Validate the DS4 endpoint URL and credentials whenever configuration changes.
- Start the DS4 server before running doctor checks.
- Use HTTPS endpoints with valid certificates.
When it happens
Trigger: Running the doctor's DS4 probe when `client.list_models()` yields Err — e.g. HTTP 401/404 from the endpoint, TLS failure, malformed base URL, or connection reset within the 15-second window.
Common situations: Wrong DS4 base URL or port; endpoint requires an API key the client lacks; endpoint does not implement `/v1/models`; self-signed or expired TLS certificate; local DS4 server not started.
Related errors
- ds4_probe_error(config, &error.to_string())
- DeepSeek
- DS4 /v1/models at did not list configured alias ' '…
- DS4 /v1/models could not be reached at
- DS4 /v1/models timed out after 15 seconds at
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/db12e3d98582b868.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/doctor.rs:579
}
/// Probe DS4 through its cheap `/v1/models` contract instead of waking the
/// model for a completion. The selected model must be advertised.
pub(crate) async fn probe_ds4_models(config: &crate::config::Config) -> anyhow::Result<()> {
use crate::client::CodewhaleClient;
use crate::core::model_client::ModelClient;
let endpoint = crate::client::redact_url_for_display(&config.active_route_base_url());
let client = CodewhaleClient::new(config)?;
let configured_alias = client.model().to_string();
let models = match tokio::time::timeout(
std::time::Duration::from_secs(15),
client.list_models(),
)
.await
{
Ok(Ok(models)) => models,
Ok(Err(error)) => anyhow::bail!(ds4_probe_error(config, &error.to_string())),
Err(_) => anyhow::bail!("DS4 /v1/models timed out after 15 seconds at {}", endpoint),
};
if !models
.iter()
.any(|available| available.id == configured_alias)
{
let advertised = models
.iter()
.take(8)
.map(|available| available.id.as_str())
.collect::<Vec<_>>()
.join(", ");
anyhow::bail!(
"DS4 /v1/models at {} did not list configured alias '{configured_alias}' (advertised: {})",
endpoint,
if advertised.is_empty() {
"none"
} else {View on GitHub (pinned to 73e0f67d83)