From 7ce928992174dbf0f21c37325b6366cfb8f0f925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 7 Aug 2026 21:47:56 +0000 Subject: [PATCH] fix(hooks): useSessionState reset honours the current default, not a frozen one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also found uncommitted in the shared tree; unrelated to agent panels, so it lands on its own. `reset` closed over `initialValue` from the first render, and its `useCallback` dep list deliberately omitted it — with an eslint-disable to silence the warning that was correctly pointing at the bug. Any caller whose default is computed (derived from props, from a fetch, from another piece of state) got reset to whatever that default happened to be on mount, which after the first render is the wrong value. Reads through a ref instead, so reset always sees the current default. The eslint-disable goes away because there is nothing left to suppress — the dep list is honest now. Co-Authored-By: Claude Opus 5 --- src/workspaces/hooks/src/useSessionState.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/workspaces/hooks/src/useSessionState.ts b/src/workspaces/hooks/src/useSessionState.ts index 5fcf7053..1b561faa 100644 --- a/src/workspaces/hooks/src/useSessionState.ts +++ b/src/workspaces/hooks/src/useSessionState.ts @@ -76,6 +76,8 @@ export function useSessionState(key: string, initialValue: T) { valueRef.current = value; const setGlobalRef = useRef(setGlobal); setGlobalRef.current = setGlobal; + const initialValueRef = useRef(initialValue); + initialValueRef.current = initialValue; const setValue = useCallback( (arg: React.SetStateAction) => { @@ -86,11 +88,11 @@ export function useSessionState(key: string, initialValue: T) { [key], ); + // Read through the ref, not the closure: resetting means "whatever the default is now", and a + // `useCallback` over `initialValue` would freeze the default from the render that built the callback. const reset = useCallback(() => { clearSessionValue(key); - setGlobalRef.current(initialValue); - // `initialValue` is read at reset time on purpose: resetting means "whatever the default is now". - // eslint-disable-next-line react-hooks/exhaustive-deps + setGlobalRef.current(initialValueRef.current); }, [key]); return [value, setValue, reset] as const;