atuinsh/atuin · error
model list request failed ({status})
Error message
model list request failed ({status}) What it means
`fetch_models` requests the model list from the AI gateway; when the HTTP response status is not a success, it bails with the status code embedded in the message. This distinguishes a rejected/failed HTTP request from transport or JSON-parsing failures.
Source
Thrown at crates/atuin-ai/src/models.rs:44
}
/// Fetch the models available to this user. Sent authenticated because the
/// server includes feature-flag-gated models only for entitled users.
pub async fn fetch_models(endpoint: &reqwest::Url, token: &str) -> Result<ModelList> {
let url = endpoint.append_path("api/cli/models")?;
let mut request = reqwest::Client::new()
.get(url)
.header(USER_AGENT, crate::stream::APP_USER_AGENT)
.timeout(Duration::from_secs(10));
if !token.is_empty() {
request = request.bearer_auth(token);
}
let response = request.send().await.context("failed to fetch model list")?;
let status = response.status();
if !status.is_success() {
eyre::bail!("model list request failed ({status})");
}
response.json::<ModelList>().await.context("failed to parse model list")
}
/// Persist the chosen alias to `ai.model` in config.toml so it becomes the
/// default for future sessions. Already-running sessions keep the model they
/// read at startup.
pub async fn save_model_selection(alias: &str) -> Result<()> {
let config_file = atuin_client::settings::Settings::get_config_path()?;
let config_str = tokio::fs::read_to_string(&config_file).await.unwrap_or_default();
let mut doc = config_str.parse::<toml_edit::DocumentMut>()?;
if !doc.contains_key("ai") {
doc["ai"] = toml_edit::table();
}
doc["ai"]["model"] = toml_edit::value(alias);
View on GitHub (pinned to c0c717ab04)
Solutions
- Check the status code in the message (401/403 => re-authenticate with the hub)
- Re-run `atuin login` / refresh the AI session token
- Verify the configured gateway URL is correct
- Retry later if the status is 5xx (server-side issue)
Defensive patterns
Strategy: retry
Validate before calling
// preflight: check token and endpoint before fetching models
let status = client.get(&url).bearer_auth(token).send().await?.status();
if status == reqwest::StatusCode::UNAUTHORIZED { reauth().await?; } Try / catch
match fetch_models(token).await {
Ok(models) => models,
Err(e) if e.to_string().contains("401") || e.to_string().contains("403") => {
reauthenticate().await?;
fetch_models(token).await?
}
Err(e) => return Err(e),
} Prevention
- Refresh hub auth tokens before long-running AI sessions
- Monitor gateway status; treat 5xx as transient and back off
- Log the status code from the message for triage
When it happens
Trigger: The model-list endpoint returns 4xx/5xx: expired or invalid bearer token, wrong gateway address, server error, or rate limiting
Common situations: Stale auth session after logout, misconfigured hub/base URL, gateway outage or maintenance
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
- usage request failed ({status})
- Hub account deletion failed with status {status}
- username already in use
- failed to parse server version: {:?}
- Server not reporting its version: it is either too old or un
AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12).
Data as JSON: /api/errors/fefbd75ca96cc296.
Report an issue: GitHub.