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.
Where
packages/system/dashboard/images/console/packages/k8s-client/src/hooks.ts:88-113(theuseK8sListwatch effect).Problem
The watch-establishing
useEffectis keyed onresourceVersion. On a watchERRORthe callback only callsqueryClient.invalidateQueries({ queryKey }), which triggers a re-list. If that re-list returns the sameresourceVersion— 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
watchGenerationcounter to state, bump it inside theERRORcallback (afterinvalidateQueries), and include it in the effect dependency list so the watch re-subscribes regardless of whetherresourceVersionchanged. Add backoff so a persistently failing watch doesn't reconnect in a tight loop. Cover with a regression test inhooks.test.tsthat simulates an ERROR event followed by a re-list returning an unchangedresourceVersionand 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.