Fix race: chat dispatched stale model id before picker loaded

↗ view on GitHub · Claude · 2026-05-16 · 30fa8010

If a user clicked Send on a freshly-loaded chat before /me/models
resolved, useSelectedModel still held the legacy default
(`gemini-3-flash-preview` or a stale localStorage value). The
backend's assertModelAllowed then rejected with "External AI
providers are disabled" even though the picker UI was about to
auto-fall-back to a valid local model. The picker just hadn't
caught up yet.

Move the validation into useSelectedModel itself: on mount it
fetches the live available-models list, validates the stored
selection against it, and only THEN emits a usable id. Returns a
third element `ready` so callers can disable Send while we don't
yet have a verified-valid selection.

ChatInput now early-returns on submit when !modelReady, and the
Send button is disabled until the list has resolved. ModelToggle's
own fallback-onChange is removed since useSelectedModel handles it
authoritatively (avoids double-emit churn).
Repository cpatpa/PIP
Author Claude <noreply@anthropic.com>
Authored
Parents afc21cea
Stats 3 files changed , +57 , -14
Part of LLM dispatch - stale model id resolution and external-disabled fallbacks

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-30fa8010.md from inside the repo you want the change in.

⬇ Download capture-commit-30fa8010.md