Skip to content

Fix terminal disconnect when toggling split pane mode#745

Merged
selfcontained merged 2 commits into
mainfrom
agt_6a705144a2ef/agent-44a2ef
Jul 10, 2026
Merged

Fix terminal disconnect when toggling split pane mode#745
selfcontained merged 2 commits into
mainfrom
agt_6a705144a2ef/agent-44a2ef

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

Summary

  • Fixes the bug where the live terminal session disconnects and shows a blank screen when entering/exiting split pane mode
  • Root cause: the split pane feature moved terminalElement between different React tree positions, causing unmount/remount which destroyed the xterm surface and WebSocket connection
  • Fix: render the terminal via createPortal into a stable container div (created once, never replaced), and use useLayoutEffect to move that container between slot divs using DOM appendChild — the portal target never changes identity, so React never unmounts the terminal

Test plan

  • Type check passes (pnpm run check)
  • Web finalization passes (pnpm run finalize:web)
  • E2E tests pass (178 passed, 12 skipped terminal-live tests)
  • Live dev server validation: terminal connects in split mode, stays connected after unsplit (DOM marker test confirms xterm element is preserved across transitions)

selfcontained and others added 2 commits July 9, 2026 15:26
The split pane feature (d94223b) moved terminalElement between different
positions in the React tree (inside ResizablePanelGroup vs. a plain div),
causing React to unmount/remount TerminalPane. The unmount destroyed the
xterm surface and closed the WebSocket, and the stale-nonce guard
prevented reconnection — resulting in a blank screen.

Fix: render terminalElement via createPortal into a stable container div
(created once, never replaced). A useLayoutEffect moves that container
between slot divs using DOM appendChild when split mode changes. Since
the portal target never changes identity, React never unmounts the
terminal component.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Detach the stable portal container from its current parent when the
effect re-runs or unmounts, ensuring it's always in a known state
rather than potentially orphaned in a stale DOM node.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@selfcontained
selfcontained merged commit c86a036 into main Jul 10, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_6a705144a2ef/agent-44a2ef branch July 10, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant