zed-industries/zed · error

Invalid model ID {}

Error message

Invalid model ID {}

What it means

After the session resolves, select_model calls model_from_id(&model_id) against the agent's current model registry; a miss means the requested AgentModelId is not in the live model list. Favorites in agent settings are matched by provider+model string after this, so a stale id fails before favorite handling.

Source

Thrown at crates/agent/src/agent.rs:2425

    fn select_model(&self, model_id: AgentModelId, cx: &mut App) -> Task<Result<()>> {
        log::debug!(
            "Setting model for session {}: {}",
            self.session_id,
            model_id
        );
        let Some(thread) = self
            .connection
            .0
            .read(cx)
            .sessions
            .get(&self.session_id)
            .map(|session| session.thread.clone())
        else {
            return Task::ready(Err(anyhow!("Session not found")));
        };

        let Some(model) = self.connection.0.read(cx).models.model_from_id(&model_id) else {
            return Task::ready(Err(anyhow!("Invalid model ID {}", model_id)));
        };

        let favorite = agent_settings::AgentSettings::get_global(cx)
            .favorite_models
            .iter()
            .find(|favorite| {
                favorite.provider.0 == model.provider_id().0.as_ref()
                    && favorite.model == model.id().0.as_ref()
            })
            .cloned();

        let LanguageModelSelection {
            enable_thinking,
            effort,
            speed,
            ..
        } = agent_settings::language_model_to_selection(&model, favorite.as_ref());

View on GitHub (pinned to bc538def45)

Solutions

  1. Pick a model from the currently available list (call list_models and use one of those ids)
  2. Update favorite_models in agent settings to ids that exist now
  3. Re-enumerate models (fix provider auth if enumeration failed) and retry

Example fix

// before
let Some(model) = self.connection.0.read(cx).models.model_from_id(&model_id) else {
    return Task::ready(Err(anyhow::anyhow!("Invalid model ID {}", model_id)));
};

// after: fall back to the default model with a visible warning
let Some(model) = self.connection.0.read(cx).models.model_from_id(&model_id) else {
    log::warn!("model {} no longer available; using default", model_id);
    let Some(model) = self.connection.0.read(cx).models.default_model() else {
        return Task::ready(Err(anyhow::anyhow!("No models available")));
    };
    model
};
Defensive patterns

Strategy: type-guard

Validate before calling

// Resolve the id against the live list before selecting
let valid_ids: HashSet<_> = connection.0.read(cx).models
    .model_list.iter().map(|m| m.id.clone()).collect();
if !valid_ids.contains(&model_id) {
    model_id = pick_from(valid_ids); // or prompt the user to re-choose
}

Type guard

fn model_id_is_available(agent: &AgentConnection, model_id: &AgentModelId, cx: &App) -> bool {
    agent.0.read(cx).models.model_from_id(model_id).is_some()
}

Try / catch

match selector.select_model(model_id, cx).await {
    Err(error) if error.to_string().starts_with("Invalid model ID") => {
        // Stale favorite: fall back to the default model and notify.
        notify(format!("{error}; using default"));
        selector.select_model(default_model_id(), cx).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Applying a model id that no longer exists: favorite_models persisted from an older catalog, model renamed/deprecated upstream, provider extension downgraded, or provider switched while an old selection persisted.

Common situations: Settings carry favorites referencing removed models; model deprecated by the provider; ids from a different provider namespace.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/0e8f9816095a58ec. Report an issue: GitHub.