This repository was archived by the owner on May 18, 2026. It is now read-only.
Repository navigation
fix(onboarding): close race that lets the wizard redirect mid-action when picking Ollama - #7
Merged
Merged
Conversation
…when picking Ollama
useLocalOllama() schedules a 800ms-delayed redirect to / after marking setup
complete, but it left the wizard fully interactive during that window. The
user could click Next, advance to Step 2, click into the API-key input, and
then get yanked to chat when the timer fired — appearing as if clicking the
input itself caused the redirect.
Fix: synchronously replace the step container with a "Setting up <model>"
loading state the moment the user clicks the Use button. The disabled
spinner button is the only control while the API calls + redirect are in
flight, so there's no stale UI to interact with.
Error paths (use-model returns ok:false, or fetch throws) now also call
renderStep(1) so the user lands back on a working Welcome step instead of
a stuck "Setting up…" screen.
Surfaced by FITB#122 ("clicked into the OpenRouter API key field, redirected
to chat").
roadhero
added a commit
that referenced
this pull request
May 6, 2026
… on late enable (#10) Two related FITB#122 bugs in the local-fallback UX surface: nesquena#122 #6 — Reactive failover modal never appears on provider failure The frontend ELIGIBLE_TYPES set was {stream_interrupted, rate_limit, no_response, unknown}. The original comment said auth/quota errors are excluded because "local model can't fix the user's wrong key / empty wallet." That misread the value: local fallback REPLACES broken cloud entirely so the user can keep working, regardless of why cloud broke. Auth and quota are exactly when the fallback offer makes sense. Backend (api/streaming.py) actually emits these types: 'auth_mismatch', 'quota_exhausted', 'stream_interrupted', 'no_response'. The previous 'rate_limit' entry was dead — backend never emits it. Reconciled with the real backend vocabulary. nesquena#122 #7 — Recovery banner never appears after enabling fallback startRecoveryPolling() was only called from boot, gated on the /api/local-fallback/status check at page load. The most common user flow — provider failure → enable fallback in Settings → correct API key → expect banner — never started polling, because at page-load fallback was off. Fix: panels.js's onLocalFallbackToggle now dispatches a 'fitb:fallback-enabled' window event after a successful enable, fallback-polish.js's boot listens for it and calls startRecoveryPolling. The function is already idempotent (returns early if the timer is set), so this is safe alongside the existing boot-time call for the steady-state case.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
useLocalOllama()schedules a 800ms-delayed redirect to/after marking onboarding complete, but it left the wizard fully interactive during that window. The user could click Next during the 800ms, advance to Step 2, click into the API-key input, and then get yanked to chat when the timer fired — appearing as if clicking the input itself caused the redirect.Surfaced by FITB#122 — the user reported "clicked into the OpenRouter API key field, redirected to chat instantly". Reproduced exactly: pick Ollama → click Next → click input → race fires → chat.
The change
When the user clicks "Use [model]", synchronously replace
step-containerwith a "Setting up [model]" loading state. The disabled spinner button is the only control while the API calls + redirect are in flight, so there's no stale UI to interact with.Error paths (
use-modelreturnsok:false, or fetch throws) now also callrenderStep(1)so a failed swap leaves the user with a working Welcome step instead of a stuck "Setting up…" screen.Test plan
POST /api/ollama/use-model→POST /api/setup/complete→GET /returns 200 (no redirect, gate lifted)setup.jsis served (the new "Setting up..." HTML appears in the response body)use-modelfailure → alert dismissed → wizard re-rendered to Step 1 (not stuck on spinner)This is the second of two FITB#122 fork-side fixes. PR #6 (merged) added the redirect exempt list; this PR closes the race UX bug. After merge, the FITB main repo will bump
forks/hermes-webuito consume both.