From bbffafded17f4f07b082ee1ed299bc4fd6a68ac5 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Tue, 25 Aug 2026 20:33:14 -0400 Subject: [PATCH] fix: resolve the servers list outside the override's state updater (#2095) `record` read `serversRef.current` from inside the `setRecords` updater. A functional updater must be pure -- React may defer or replay it -- so the pairing resolved at whatever moment the updater happened to run rather than when the record was written. A list read committing in between would then be paired with the record as its baseline, and the very read that should have superseded the override would instead certify it. Read the list once, at call time, and use it for both the pairing and the prune. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh Signed-off-by: cliffhall --- clients/web/src/hooks/usePaginatedListsOverride.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clients/web/src/hooks/usePaginatedListsOverride.ts b/clients/web/src/hooks/usePaginatedListsOverride.ts index ec9a7b71..fa00343b 100644 --- a/clients/web/src/hooks/usePaginatedListsOverride.ts +++ b/clients/web/src/hooks/usePaginatedListsOverride.ts @@ -82,8 +82,13 @@ export function usePaginatedListsOverride( }, [servers]); const record = useCallback((serverId: string, value: boolean) => { + // Read outside the updater. A functional updater must be pure — React may + // defer or replay it — and this one would otherwise resolve the ref at + // whatever moment it happened to run. A list read committing in between + // would then be paired with the record as its baseline, so the very read + // that should have superseded the override would instead certify it. + const list = serversRef.current; setRecords((previous) => { - const list = serversRef.current; const next = new Map(); // Carry forward only the records the list has not moved past, so a // session that toggles across many servers does not accumulate a record