Repository navigation
Description
Where
packages/system/dashboard/images/console/packages/k8s-client/src/hooks.ts:88-113 (the useK8sList watch effect).
Problem
The watch-establishing useEffect is keyed on resourceVersion. On a watch ERROR the callback only calls queryClient.invalidateQueries({ queryKey }), which triggers a re-list. If that re-list returns the same resourceVersion — common after a brief proxy/network blip where nothing changed server-side — the effect's dependency array is unchanged, so the effect never re-runs and the closed watch connection is never re-established. The view then silently stops receiving live updates until a full remount (navigating away and back), leaving it permanently stale.
Impact
Any list-backed console view (applications, services, VMs, etc.) can go stale after a transient watch drop with no visible error. Low-frequency but confusing: the UI looks healthy and simply stops updating.
Fix sketch
Add a watchGeneration counter to state, bump it inside the ERROR callback (after invalidateQueries), and include it in the effect dependency list so the watch re-subscribes regardless of whether resourceVersion changed. Add backoff so a persistently failing watch doesn't reconnect in a tight loop. Cover with a regression test in hooks.test.ts that simulates an ERROR event followed by a re-list returning an unchanged resourceVersion and asserts the watch is re-opened.
Provenance
Pre-existing upstream behavior carried in verbatim by the cozystack-ui vendoring (#2963); flagged as non-blocking finding 1 in that PR's review. Now trackable in-tree.
Activity
myasnikovdaniil commentedon Aug 16, 2026
State: real and unfixed, and deliberately kept out of the small-fixes batch in #3837.
It lives in
packages/k8s-clientrather than the console:hooks.tskeeps no watch generation andclient.tsnever reconnects, so a dropped watch leaves the list silently stale rather than erroring. The fix is roughly 25 lines plus a new test file, but it needs a backoff design rather than a one-liner, which is why it wants its own pull request.