Guard Plugins page reloads against a stale tenant's late fetch - #442
Merged
TheGreatAxios merged 4 commits intoAug 29, 2026
Merged
TheGreatAxios merged 4 commits into
TheGreatAxios merged 4 commits into
Conversation
Proves a fast bench switch doesn't let a slower tenant's late plugins/skills fetch overwrite the newly selected tenant's state.
reloadPlugins/reloadSkills had no cancellation, so switching benches while a fetch was still in flight could let the previous tenant's response land after the new tenant's and overwrite its state. Both effects now track a cancelled flag in their cleanup, the same pattern people-section.tsx already uses, and the effect itself owns re-fetching (via a reload key) so the existing imperative reloadPlugins/reloadSkills call sites still refresh the current tenant. Fixes CL-7138.
…leton Proves a connect/disconnect-triggered reload keeps the gallery on screen and swaps in fresh data when it lands, instead of tearing down to the full loading skeleton on every imperative reload.
The reload-key restructure from the previous commit made every imperative reload (a connect/disconnect panel's onChanged, the error screen's Retry) re-run the fetch effect, which unconditionally set status: "loading" and tore the page down to the full skeleton — a regression from main, where an imperative reload just fetched and swapped in the result. Each effect now tracks the tenant it last fetched for in a ref and only shows the loading state when selectedTenantId actually changed; a same-tenant reload keeps whatever is on screen until the fresh data (or a new error) lands. Fixes CL-7138.
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 CL-7138 — https://linear.app/abklabs/issue/CL-7138
Problem
apps/web/src/pages/plugins-page.tsx:95-121ranreloadPlugins/reloadSkillsas.then(setState).catch(setState)chains with no cancellation. Both effects re-ran onselectedTenantId, but a fast bench switch could leave the previous tenant's fetch in flight; if it resolved after the new tenant's fetch, its response overwrote the newly selected tenant's state, so the Plugins page could momentarily (or persistently, on a slow response) show the wrong bench's plugins/skills.Change
cancelledflag set in their cleanup (the pattern already used inpackages/settings-ui/src/people-section.tsx:106-154) and only callsetStatewhen!cancelled.selectedTenantIdplus apluginsReloadKey/skillsReloadKeycounter; the existing imperativereloadPlugins/reloadSkillscall sites (connect/disconnect panel, retry button, skill creation) now just bump that counter, so they still refresh the current tenant without duplicating fetch logic outside the effect.status: "loading"whenselectedTenantIdactually changed — a same-tenant reload (connect/disconnect, Retry) keeps whatever is on screen and swaps in the fresh result when it lands, instead of tearing the page down to the full loading skeleton on every reload.Tests
apps/web/test/plugins-page.test.tsx:cd apps/web && bun test ./test/plugins-page.test.tsx— 9 pass.cd apps/web && bun run typecheck— clean.bunx prettier --write+bunx eslinton both changed files — clean.Full
bun run checknot run locally (shared-machine load).