astrid-runtime/astrid · error
models endpoint returned HTTP {}
Error message
models endpoint returned HTTP {} What it means
fetch_options requires the models endpoint to return a successful HTTP status and otherwise throws with the status code. Operator-supplied endpoints may return 401/404/500 etc., and the error is surfaced so callers can fall back to free-text input.
Source
Thrown at crates/astrid-cli/src/commands/capsule/model_discovery.rs:233
"withholding options-from bearer: fetch host does not match the \
configured provider ({PROVIDER_BASE_URL_KEY}) host"
);
false
},
});
let client = reqwest::Client::builder()
.user_agent("astrid-cli")
.timeout(std::time::Duration::from_secs(15))
.build()?;
let mut request = client.get(&url);
if let Some(token) = bearer {
request = request.bearer_auth(token);
}
let response = request.send().await?;
anyhow::ensure!(
response.status().is_success(),
"models endpoint returned HTTP {}",
response.status()
);
// Cap the body: the endpoint is operator-supplied and otherwise
// unbounded. Reject up-front on an advertised over-limit length so a
// hostile `Content-Length` can't even start a large transfer (fast
// path), then stream-read with the same bound so an absent/lying length
// (e.g. a chunked response with no `Content-Length`) cannot OOM the
// installer either. An over-limit response errors → free-text fallback.
anyhow::ensure!(
response
.content_length()
.is_none_or(|len| len <= MAX_RESPONSE_BYTES as u64),
"models response too large (advertised {} bytes; limit {MAX_RESPONSE_BYTES})",
response.content_length().unwrap_or_default()
);View on GitHub (pinned to affd8760f4)
Solutions
- Check the endpoint URL is the correct models path on a running server
- Set/correct the bearer token in the capsule config for authenticated endpoints
- Inspect the returned HTTP status (in the error text) and fix server-side cause (auth, routing, health)
Example fix
// before endpoint = "https://host/api/models" // 404 // after endpoint = "https://host/v1/models" // 200
Defensive patterns
Strategy: try-catch
Validate before calling
let resp = reqwest::get(&url).await?;
if !resp.status().is_success() {
eprintln!("endpoint unreachable, status {}", resp.status());
return Ok(()); // use free-text fallback
} Try / catch
match fetch_options(opts, values).await {
Err(e) if e.to_string().contains("models endpoint returned HTTP") => {
eprintln!("Discovery failed ({}); enter the model name manually.", e);
prompt_free_text()?
}
other => other?,
} Prevention
- Verify bearer tokens and endpoint paths against the server's API docs
- Curl the models endpoint manually to confirm 200 responses before configuring
- Monitor server health/auth expiry for endpoints used in capsules
When it happens
Trigger: The GET request to the resolved models URL returns a non-success status — wrong API path, missing/invalid bearer token (401), server error (5xx), or wrong port/host.
Common situations: Expired or missing API token against an OpenAI-compatible server; endpoint path typo (e.g. /v1/model vs /v1/models); server down or behind a proxy returning errors.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- GitHub API returned {} fetching release {resolved_ref} of {o
- GitHub API error querying release tag {candidate} for {org}/
- GitHub API returned {} for {org}/{repo} latest release
- no GitHub releases found for {org}/{repo}
- GitHub API rate limit exceeded - try again later
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/7da942344736e645.
Report an issue: GitHub.