From 658e6fae760909342ceed1e7bd2410721908f44b Mon Sep 17 00:00:00 2001 From: harshitsinghbhandari <24b4506@iitb.ac.in> Date: Thu, 11 Jun 2026 22:11:39 +0530 Subject: [PATCH] fix(renderer): stabilize onResize ref to prevent rrp constraint race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap handleInspectorResize in useCallback so rrp v4's panel registration useLayoutEffect (which includes onResize in its dep array) does not de-register/re-register the inspector panel on every render. Without this, any re-render of SessionView (workspace data arriving, daemon status change, etc.) created a new handleInspectorResize reference, triggering rrp's cleanup → re-registration cycle. With React 19's automatic batching, this window reliably overlapped with the expand()/collapse() useEffect on initial sidebar click, causing the "Panel constraints not found for Panel inspector" throw that tore down the session view. Fixes #185. Co-Authored-By: Claude Sonnet 4.6 --- .../src/renderer/components/SessionView.tsx | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/frontend/src/renderer/components/SessionView.tsx b/frontend/src/renderer/components/SessionView.tsx index 8f19ad3..56fc797 100644 --- a/frontend/src/renderer/components/SessionView.tsx +++ b/frontend/src/renderer/components/SessionView.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { useCallback, useEffect, useRef } from "react"; import type { PanelImperativeHandle, PanelSize } from "react-resizable-panels"; import { CenterPane } from "./CenterPane"; import { SessionInspector } from "./SessionInspector"; @@ -116,16 +116,23 @@ export function SessionView({ sessionId }: SessionViewProps) { // data-separator="active" only during a pointer drag — the same hook the // transition-suppressing CSS keys on, so drag writes are never transition // frames. - const handleInspectorResize = (size: PanelSize) => { - if (inspectorSeparatorRef.current?.getAttribute("data-separator") !== "active") return; - const open = useUiStore.getState().isInspectorOpen; - if (size.asPercentage > 0) { - window.localStorage?.setItem(inspectorSplitStorageKey, String(size.asPercentage)); - if (!open) toggleInspector(); - } else if (open) { - toggleInspector(); - } - }; + // Also wrapped in useCallback: rrp v4's panel registration useLayoutEffect + // includes onResize in its dep array, so an unstable reference would + // de-register/re-register the inspector panel on every render and race + // with the expand()/collapse() effect above. + const handleInspectorResize = useCallback( + (size: PanelSize) => { + if (inspectorSeparatorRef.current?.getAttribute("data-separator") !== "active") return; + const open = useUiStore.getState().isInspectorOpen; + if (size.asPercentage > 0) { + window.localStorage?.setItem(inspectorSplitStorageKey, String(size.asPercentage)); + if (!open) toggleInspector(); + } else if (open) { + toggleInspector(); + } + }, + [toggleInspector], + ); if (!session && !workspaceQuery.isLoading) { return (