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
- Select a default language model in the agent settings UI, then resend the prompt
- Set a model override on the thread or switch to a profile that has one
- Re-authenticate the provider so the configured model resolves again
- 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
- Set an explicit default model in agent settings for every profile you use
- Assert model().is_some() in tests and tooling that drive threads headlessly
- Re-check model resolution after provider sign-out or settings import
- Catch NoModelConfiguredError at the UI boundary and prompt for model selection
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
- No models available
- Invalid model ID {}
- Model not found
- Provider not found
- Compaction produced an empty summary
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/be73e33e82599096.
Report an issue: GitHub.