Hmbown/CodeWhale · error

Failed to list models: HTTP {status}: {error_text}

Error message

Failed to list models: HTTP {status}: {error_text}

What it means

`list_models()` issues `GET {base_url}/models` through the retrying transport and bails when the HTTP status is not 2xx. The response body is read with a 64KB cap and sanitized (provider display name, status code, secret redaction) before being embedded, so the message shows the provider's own error text safely. This is the model-picker's discovery call.

Source

Thrown at crates/tui/src/client.rs:2105

            .to_string();

        Ok(translated)
    }

    /// List available models from the provider.
    pub async fn list_models(&self) -> Result<Vec<AvailableModel>> {
        let url = api_url(&self.base_url, "models");
        let response = self.send_with_retry(|| self.http_client.get(&url)).await?;

        let status = response.status();
        if !status.is_success() {
            let raw_error_text = bounded_error_text(response, ERROR_BODY_MAX_BYTES).await;
            let error_text = sanitize_http_error_body(
                Some(self.api_provider.display_name()),
                status.as_u16(),
                &raw_error_text,
            );
            anyhow::bail!("Failed to list models: HTTP {status}: {error_text}");
        }
        let response_text = response
            .text()
            .await
            .context("Failed to read models response body")?;

        parse_models_response(&response_text)
            .map(|models| apply_provider_model_cutline(self.api_provider, models))
    }

    /// The catalog provider id for this client (the `ProviderKind` slug, falling
    /// back to the `ApiProvider` slug for legacy variants without a kind). This
    /// is the id used as the cache scope and `CatalogOffering.provider`.
    fn catalog_provider_id(&self) -> String {
        self.api_provider
            .kind()
            .map(|kind| kind.as_str().to_string())
            .unwrap_or_else(|| self.api_provider.as_str().to_string())

View on GitHub (pinned to 8880682c63)

Solutions

  1. Check the status code in the message: 401/403 → fix the API key for that provider; 404 → the endpoint does not serve `/models`.
  2. Correct the base_url so `{base_url}/models` resolves (verify with `curl -s $BASE_URL/models -H "Authorization: Bearer $KEY"`).
  3. If the server genuinely has no models route, configure the model id explicitly instead of relying on listing.
  4. 429/5xx: wait and retry; the error text from the provider usually states the quota or outage reason.

Example fix

# before
base_url = "https://my-gateway/api"          # 404 on /api/models
# after
base_url = "https://my-gateway/api/v1"      # /api/v1/models exists
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap preflight before rendering a model picker.
async fn models_endpoint_ok(base_url: &str, key: &str) -> bool {
    let url = format!("{base_url}/models");
    reqwest::Client::new().get(&url).bearer_auth(key).send().await
        .is_ok_and(|r| r.status().is_success())
}

Try / catch

match client.list_models().await {
    Ok(models) => render_picker(models),
    Err(e) if e.to_string().contains("Failed to list models: HTTP 404") => {
        // endpoint has no /models route: fall back to manual model entry
        render_manual_model_entry(),
    }
    Err(e) if e.to_string().contains("HTTP 401") || e.to_string().contains("HTTP 403") => prompt_for_api_key(),
    Err(e) => show_error(e),
}

Prevention

When it happens

Trigger: 401/403 when the API key is missing, wrong, or lacks scope; 404 when the provider or proxy does not expose `/models` at the configured base_url (wrong `/v1` prefix, gateway without a models route); 429 when rate-limited before listing; 5xx upstream outages.

Common situations: Custom OpenAI-compatible servers (llama.cpp, some vLLM/LiteLLM setups) that omit or disable the models listing route; base_url with a doubled or missing version path; expired or mistyped API key; corporate proxies blocking GET on unknown paths.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/09a9d14b0665b055. Report an issue: GitHub.