zed-industries/zed · error · NoModelConfiguredError

no language model configured

Error message

no language model configured

What it means

Thread::send_existing resolves the language model for the turn via self.model() and returns NoModelConfiguredError ('no language model configured') when that resolution yields None. The model is picked from the thread-level override, the active profile, or the agent default-model setting; if none of them produces a usable model, the turn cannot start.

Source

Thrown at crates/agent/src/thread.rs:2515

        T: Into<UserMessageContent>,
    {
        let content = content.into_iter().map(Into::into).collect::<Arc<_>>();
        log::debug!("Thread::send content: {:?}", content);

        self.messages
            .push(Arc::new(Message::User(UserMessage { id, content })));
        cx.notify();

        self.send_existing(cx)
    }

    pub fn send_existing(
        &mut self,
        cx: &mut Context<Self>,
    ) -> Result<mpsc::UnboundedReceiver<Result<ThreadEvent>>> {
        let model = self
            .model()
            .ok_or_else(|| anyhow!(NoModelConfiguredError))?;

        log::info!("Thread::send called with model: {}", model.name().0);
        self.advance_prompt_id();

        log::debug!("Total messages in thread: {}", self.messages.len());
        self.run_turn(cx)
    }

    /// Force a manual context compaction using the summary strategy,
    /// regardless of the current token usage or context window size.
    pub fn compact(
        &mut self,
        id: ClientUserMessageId,
        cx: &mut Context<Self>,
    ) -> Result<mpsc::UnboundedReceiver<Result<ThreadEvent>>> {
        let model = self
            .compaction_model(cx)
            .ok_or_else(|| anyhow!(NoModelConfiguredError))?;

View on GitHub (pinned to bc538def45)

Solutions

  1. Select a default language model in the agent settings UI, then resend the prompt
  2. Set a model override on the thread or switch to a profile that has one
  3. Re-authenticate the provider so the configured model resolves again
  4. In embedding code, catch this error and surface a model-picker prompt instead of failing silently

Example fix

// before
let events = thread.update(cx, |thread, cx| thread.send_existing(cx))?;

// after
if thread.read(cx).model().is_none() {
    open_model_picker(cx);
    return Ok(());
}
let events = thread.update(cx, |thread, cx| thread.send_existing(cx))?;
Defensive patterns

Strategy: validation

Validate before calling

// Run before sending: make sure a model resolves for this thread.
fn has_configured_model(thread: &Entity<Thread>, cx: &App) -> bool {
    thread.read(cx).model().is_some()
}

Type guard

fn resolved_model(
    thread: &Entity<Thread>,
    cx: &App,
) -> Option<Arc<dyn LanguageModel>> {
    thread.read(cx).model().cloned()
}

Try / catch

let events = match thread.update(cx, |thread, cx| thread.send_existing(cx)) {
    Ok(events) => events,
    Err(err) if err.is::<NoModelConfiguredError>() => {
        open_model_picker(cx);
        return Ok(());
    }
    Err(err) => return Err(err),
};

Prevention

When it happens

Trigger: Calling send or send_existing on a thread where no default model is set in AgentSettings, the thread and active profile carry no model override, or the configured model's provider is signed out or otherwise unavailable so the model id no longer resolves.

Common situations: Fresh install where no model was ever selected; the user signed out of the provider or removed its API key; settings.json hand-edited to an invalid model id; a subagent or automated send firing before model selection completes.

Related errors


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