fix(onboarding): show real install errors and fix concurrent install state - #2658
Merged
Conversation
…state Two bugs in the onboarding runtime setup screen and the Doctor settings panel: Bug A: RuntimeCard received the detailed install error string (step, stderr, exit code, actionable hint) via installResults state but rendered a hardcoded 'Installation couldn't be completed. Try again.' tooltip instead. The rich string from getInstallErrorMessage was computed and stored, then thrown away at render. Fix: pass installError as detail to RuntimeErrorTooltip. Add whitespace-pre-line to the tooltip content span so hint + step blocks render on separate lines. Bug B: RuntimeProvidersSection (onboarding) and DoctorSettingsPanel shared one useInstallAcpRuntimeMutation instance across all runtime cards/rows. react-query v5 per-mutate callbacks (onSuccess/onError) only fire for the latest mutate() call on a shared instance — starting install B silently drops install A's result callback. Additionally, isPending and mutation.variables tracked only the latest call, so card A's spinner vanished as soon as card B's install started. Fix: move useInstallAcpRuntimeMutation into each RuntimeCard / RuntimeRow so every card owns its own mutation instance with independent isPending and callbacks. RuntimeProvidersSection's shared installMutation and handleInstall are removed; DoctorSettingsPanel's lifted installResults / installingIds / handleInstall are replaced by per-row state. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
F1 (Doctor stale error): add resetEpoch prop to RuntimeRow; DoctorSettingsPanel bumps epoch on Check again; RuntimeRow useEffect([resetEpoch]) clears local installResult so stale failures are gone after a catalog refetch. F2 (no concurrent regression test): extend e2eBridge with installAcpRuntimeByRuntime config supporting per-runtime delay/result/call-sequences with independent counters. Add Doctor concurrent + stale-clear E2E test (08) and onboarding concurrent E2E test (both-fail-one-succeeds with rich multiline tooltip). F3 (tooltip visually clipped): RuntimeErrorTooltip content now has max-h-48 overflow-y-auto break-words in addition to whitespace-pre-line, bounding tall/wide stderr output. Doctor test assertion: codex success banner (installSuccess && availability != 'available') races with the catalog refresh that immediately returns availability 'available'. Assert codexToggle.toBeChecked() instead — stable whether isOn is driven by installSuccess or isAvailable. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
… CSS
The previous tooltip E2E test fed a short 5-line payload and used
toContainText() — passes with or without max-h-48/break-words.
Replace fixture with a 19-line realistic Windows EACCES error including
a long unbroken path (C:\Users\...\claude-agent-acp.exe) that exercises
both overflow axes. Add overflow dimension assertions on the detail span:
• scrollHeight > clientHeight: proves max-h-48 + overflow-y-auto are active
(without them, tall content has no scroll container; assertion fails)
• scrollTop can advance: proves the span actually scrolls
• scrollWidth <= clientWidth: proves break-words prevents horizontal overflow
(verified red-on-old: removing break-words causes this assertion to fail)
Also add overflow-x-hidden to RuntimeErrorTooltip's detail span so that
overflow-y: auto and overflow-x: hidden together make the scroll container
unambiguous on both axes. Locator uses page.locator().first() because
Radix tooltip portals place a visible copy and a hidden duplicate in the DOM.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Member
Author
UI states — PR #2658Onboarding: rich install-error tooltipBounded, scrollable dark tooltip showing the real npm EACCES stderr; long Windows path wraps instead of overflowing horizontally. Onboarding: concurrent installs — independent card statesBoth Claude Code and Codex installs in flight simultaneously; each card tracks its own state independently (no last-caller-wins drop). Doctor: row error — real step failure detailDoctor panel Codex row after a failed install, showing the actual step stderr ("npm ERR! code E404 / npm ERR! 404 Not Found") instead of the generic message. Doctor: Check again — stale error clearedSame Claude Code row after clicking "Check again": the stale install error is cleared via resetEpoch, row returns to healthy state. |
wpfleger96
pushed a commit
that referenced
this pull request
Jul 24, 2026
wpfleger96
added a commit
that referenced
this pull request
Jul 24, 2026
## Buzz Desktop release v0.4.25 ### Changes since v0.4.24: - fix(discovery): spawn PowerShell install commands natively on Windows ([#2750](#2750)) ([`f3981dbfe`](f3981db)) - fix(desktop): use augmented PATH for model discovery subprocess ([#2753](#2753)) ([`3bd3a014c`](3bd3a01)) - Improve huddle audio failure handling ([#2578](#2578)) ([`fb4a801ad`](fb4a801)) - fix(onboarding): show real install errors and fix concurrent install state ([#2658](#2658)) ([`9731cd818`](9731cd8)) - feat(node): add Windows managed Node.js fallback (win-x64 + win-arm64) ([#2661](#2661)) ([`596386ee5`](596386e)) - fix(desktop): parse runtime team instructions section ([#2645](#2645)) ([`269ef357f`](269ef35)) - Match create-channel template selector styling ([#2654](#2654)) ([`72bbaece4`](72bbaec)) - feat(desktop): make pull request reviews actionable ([#2510](#2510)) ([`9081ab0ec`](9081ab0)) - fix(desktop): shared-compute usability — share toggle, usage indicator, model resync ([#2448](#2448)) ([`9cc9652c7`](9cc9652)) - fix(desktop): refine focused thread dismissal targets ([#2644](#2644)) ([`c86c4f59c`](c86c4f5)) - Clarify agent harness defaults in create flow ([#2601](#2601)) ([`76aeae703`](76aeae7)) - fix: expose community icon control on open relays ([#2640](#2640)) ([`e341b09cb`](e341b09)) **To release:** merge this PR. The tag and build will happen automatically.
wpfleger96
added a commit
that referenced
this pull request
Jul 24, 2026
…stallSuccess plumbing Rebase conflict resolution in the prior commit incorrectly preserved main's #2658 per-card mutation architecture while dropping three Atish-authored hunks: - guidance div (doctor-runtime-guidance-*) missing from RuntimeRow - not_installed availability not included in CLI-needed chip branch - installSuccess binding restored instead of deleted; installSuccess banner kept This commit replaces the panel with Atish's final state from ca34471: - guidance div reinserted between RuntimeHeader and config_invalid paragraph - not_installed added to CLI-needed chip (alongside cli_missing) - installSuccess variable, prop threading through Row/Header/Actions, isOn computed var, disabled expression, and green banner all removed - data-testid on install-error paragraph preserved (added by fc15d79) - per-card resetEpoch architecture from #2658 kept (Atish's final intent) Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.




Fixes two bugs in the ACP runtime setup screen (onboarding) and Doctor settings panel that caused users to see unhelpful generic errors on install failure and lose the first install's state when starting two installs back-to-back.
What this fixes
Bug A — real install errors discarded in onboarding.
RuntimeCardreceived the detailed install error string fromgetInstallErrorMessage(step name, stderr, exit code, actionable hint) but rendered a hardcoded"Installation couldn't be completed. Try again."tooltip regardless of the actual failure. The rich string was computed and stored ininstallResultsstate, then ignored at render. Fix: passinstallErrorasdetailtoRuntimeErrorTooltip. Addwhitespace-pre-lineto the tooltip content span so multi-line hint + step-detail strings render correctly.Users on Windows with no Node.js will now see the actual Git Bash error and the actionable hint instead of a generic message. Users with npm permission issues on macOS see the
EACCESdetail and thenpm config set prefixremediation hint.Bug B — concurrent installs lose the first card's state.
RuntimeProvidersSection(onboarding) andDoctorSettingsPaneleach shared oneuseInstallAcpRuntimeMutation()instance across all runtime cards/rows. react-query v5 per-mutate()callbacks (onSuccess/onError) only fire for the latestmutate()call on a shared instance — starting install B silently drops install A's result callback, so card A never shows success or failure. Additionally,isPendingandmutation.variablestracked only the latest call, making card A's spinner vanish mid-install when card B started.Fix: move
useInstallAcpRuntimeMutation()into eachRuntimeCard(onboarding) andRuntimeRow(Doctor panel) so every card owns its own mutation instance with independentisPendingand callbacks. The sharedinstallMutation+handleInstallinRuntimeProvidersSectionand the liftedinstallResults/installingIds/handleInstallinDoctorSettingsPanelare removed.Non-happy-path scenarios
onErrorfires independently, A's card shows the error, B's spinner continues unaffected.onErrorfires separately, both show their own error detail.The
RETRY INSTALLlabel flow (installError → installLabelinRuntimeStatus) is unchanged — retrying a card's install clears its prior result and re-fires its own mutation.Files changed
desktop/src/features/onboarding/ui/SetupStep.tsx—RuntimeCardowns its mutation;RuntimeProvidersSectionshared mutation removeddesktop/src/features/onboarding/ui/RuntimeErrorTooltip.tsx—whitespace-pre-lineon tooltip contentdesktop/src/features/settings/ui/DoctorSettingsPanel.tsx—RuntimeRowowns its mutation + result state; section-level lifted state removeddesktop/src/shared/lib/installError.test.mjs— two new test cases: double-newline separator format and multi-step last-step-only behavior