diff --git a/src/app/runtime/actions/mod.rs b/src/app/runtime/actions/mod.rs index e069bdc..24fc7a0 100644 --- a/src/app/runtime/actions/mod.rs +++ b/src/app/runtime/actions/mod.rs @@ -725,6 +725,23 @@ fn spawn_turn(state: &AppStateRest) { .find(|role| role.provider == state.settings.provider && role.model == state.settings.model) .and_then(|role| role.context_window) .unwrap_or(state.app_config.default_context_window) as usize; + // The selected provider has no entry in app_config at all (e.g. the + // Claude-settings auto-detection that registers "claude" found nothing + // this run). Without this check, LlmClient::new silently falls back to + // the zen default base URL while keeping this provider's model name — + // a mismatched request that reaches a real server and comes back as a + // confusing "Missing API key" 401 from an unrelated provider, instead + // of the actual problem: the configured provider doesn't exist. + if base_url.is_none() { + if let Ok(mut q) = state.turn_events.lock() { + q.push_back(TurnEvent::Error(format!( + "Provider '{}' is not configured — no matching entry found. \ + Pick a different provider in Settings, or configure it.", + state.settings.provider + ))); + } + return; + } if api_key.is_empty() { if let Some(provider_cfg) = state.app_config.providers.get(&state.settings.provider) { api_key = provider_cfg.api_key_env.as_ref()