Glass/Agents layout: per-chat terminal panel missing after switching sidebar conversations

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

In Cursor 3.x Glass (Agents Window) layout, each agent chat used to keep a sticky terminal panel on the right. After recent updates, switching between chats in the left sidebar (including across different workspace folders/projects) sometimes returns to a chat where the agent conversation is still there, but the associated terminal panel is gone.

This is not just blank terminal text (a rendering issue). The whole terminal pane for that chat is missing or not rebound. The chat history and agent UI load fine; only the per-conversation terminal state fails to restore.

This breaks multi-project workflows where you keep parallel agent sessions with running terminals and expect each chat to restore its own terminal when you click back to it.

Steps to Reproduce

  1. Open Cursor in Glass/Agents mode (glassMode: true).
  2. Use layout with chat/agent list on the left sidebar and integrated terminal on the right.
  3. Open Project A (e.g. one repo folder), start an agent chat, let the agent run shell commands so a terminal session is active on the right.
  4. Open Project B (different folder), start another agent chat with its own terminal activity.
  5. Switch back and forth between chats via the left sidebar (within the same project or across projects).
  6. After several switches (intermittent; not always on the first switch), return to a chat that previously had a visible terminal.

Observed: chat/conversation UI and history remain, but the right-side terminal panel is missing. Sometimes the panel can be forced back via Terminal menu, but the original per-chat terminal binding/session is lost.

Expected Behavior

When re-selecting an agent chat in the sidebar, Cursor should restore that conversation’s bound terminal panel and terminal session state, the same way it did in earlier builds. Each composer/chat should have independent, persistent terminal layout state across sidebar navigation.

Operating System

Windows 10/11

Version Information

Version: 3.8.16
VSCode Version: (Cursor 3.8.16 build)
Commit: 6064a4a629d1bc5b421bce9e9dc8c5967c111640
Release Track: dev
Electron/Chromium: bundled with Cursor 3.8.16
OS: Windows 10 Pro 10.0.19045 x64

For AI issues: which model did you use?

Composer 2.5 (Agent mode) — issue is UI/layout, not model-specific

Additional Information

Layout: Glass/Agents Window (glassMode: true in storage.json). Chat list left, terminal right.

Shell: PowerShell (WSL/Git Bash profiles also configured).

GPU: NVIDIA GeForce GTX 1660 SUPER (32.0.16.1047) + Intel UHD Graphics 770 (32.0.101.7085).

Relevant settings: update.releaseTrack: dev, cursor.terminal.usePreviewBox: true, cursor.agent_layout_browser_beta_setting: true.

Local state evidence (may help debug): Per-agent panel visibility is stored in globalStorage/state.vscdb under keys like glass/cursor.editorPanelVisibility.agent/{composerId} with {visible: boolean, updatedAtMs}. On this machine, 19 chats have visible: true and 2 have visible: false, suggesting per-composer terminal panel state is tracked but not always restored correctly on chat switch.

Related forum threads (similar but not identical):

  • UI constantly resets layout in Cursor 2.0 (#139511) — terminal panel vanishes
  • Non-sticky editor layout (#157201) — layout state not persisted across mode switches
  • Secondary sidebar terminal regression (#149126) — terminal/chat tab routing issues on right panel
  • Integrated Terminal Text Disappears When Switching to AI Chat (#138096) — rendering bug, distinct from whole panel missing

Workarounds tried / partial:

  • Terminal menu → New Terminal sometimes restores a panel but not the original per-chat session
  • glass.toggleTerminal may show a terminal but not rebind the chat-specific one
  • GPU acceleration off / Legacy Terminal Tool — addresses rendering freezes, not this layout persistence issue

Request: Please treat this as a Glass per-composer layout/terminal binding regression. Happy to provide state.vscdb excerpts if needed.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey, thanks for the report. It’s really detailed, and extra thanks for the repro steps and for digging into the editorPanelVisibility.agent/{composerId} keys. That helps a lot.

This is an area where we already have a few related reports about panels restoring when switching between chats in the Agents Window, but we haven’t been able to reproduce this exact case where the terminal panel fully disappears after switching in the sidebar. It looks like a client-side layout state issue, and we don’t see anything on the server side, so it’s hard to move forward without a repro.

To speed this up, you mentioned you can share a screen recording and an excerpt from state.vscdb. If you can, please send:

  • A short screen recording of the moment the panel disappears, so we can see how many switches it takes and the scenario, like single project or across projects.
  • An excerpt of glass/cursor.editorPanelVisibility.agent/{composerId} for a couple of chats where the bug happened, with the visible and updatedAtMs values before and after switching if possible.

I’ve filed an internal issue for this specific variant. I can’t share an ETA for a fix yet, but I’ll post an update in the thread if we have one.

Follow-up with additional symptoms and the state.vscdb excerpt you asked for.

**Frequency:** Several times per day.

**Strongest repro pattern:**

1. Have 2 agent chats active in the sidebar (often across projects, e.g. hermes + another repo).

2. Each chat has its own terminal on the right, agents running shell work in parallel.

3. Work in chat B for ~15-30 minutes.

4. Click back to chat A in the sidebar.

5. Chat A loads fine (history, agent UI) but the terminal that was running there is gone. I did not close it.

**Additional symptom - terminal identity gets crossed:**

Sometimes when I click into a sidebar chat, the terminal panel shows a name/label from a different chat. If I then go back to the original chat, that chat’s terminal is missing entirely. Per-chat terminal mapping seems to get confused, not just hidden.

**Live example (happening right now):**

- Sidebar chat (web3sec) general under hermes selected - had a terminal on the right running agent work.

- hermes main workspace chat also had its own terminal.

- Both terminals disappeared from the UI at the same time without me closing either. Right panel is empty.

**state.vscdb excerpt (pulled while bug is active):**

```

glass/cursor.editorPanelVisibility.agent/c26e779c-10c8-44b8-9750-c2219ddd3ca2

visible: true

updatedAtMs: 2026-06-20 18:42 UTC

workspace: c:\Users\PC\Documents\GitHub\hermes\agents\web3sec

→ web3sec general chat. Terminal NOT shown in UI.

glass/cursor.editorPanelVisibility.agent/c824a66a-8c59-4815-995e-2e852b5a5f8c

visible: true

updatedAtMs: 2026-06-20 18:42 UTC

workspace: c:\Users\PC\Documents\GitHub\hermes

→ hermes main chat. Terminal NOT shown in UI.

```

Both composers have visible: true in persisted state while the terminal panel is empty in Glass. Looks like a state/render desync - layout state thinks the panel should be visible but the terminal is not bound or not rendered.

Only 2 composers on this machine have visible: false (older/draft chats). The currently affected chats still read visible: true.

Other relevant keys:

- terminal.hidden: [{“id”:“terminal”,“isHidden”:false}]

- cursor/terminalExecutionServiceV3HealthCheckResult: passed

Happy to pull before/after snapshots for specific composer IDs on request.

Update after full Cursor restart:

Symptom is gone for now. I have (MAIN) hermes and (web3sec) general both with running terminals, swapping back and forth in the sidebar, and the UI looks correct.

However I ran a local state dump while the UI is healthy, and the workspace-level DB still looks odd. So workspace SQLite may not be a reliable indicator of whether Glass terminals are actually bound/rendered.

**Baseline dump (UI healthy, terminals visible, 2026-06-21 ~00:43 UTC):**

```

GLOBAL web3sec (c26e779c…): editorPanelVisibility.visible = true

GLOBAL hermes (c824a66a…): editorPanelVisibility.visible = true

WORKSPACE web3sec:

cursor/agentLayout.panelVisible = false

terminal = {“terminal”:{“collapsed”:false,“isHidden”:true}}

terminal.integrated.layoutInfo = MISSING

WORKSPACE hermes:

cursor/agentLayout.panelVisible = false

terminal = {“terminal”:{“collapsed”:false,“isHidden”:true,“size”:2235}}

terminal.integrated.layoutInfo = {“tabs”:[]}

workbench.panel.hidden = true

```

So when the bug was active earlier, we had a similar workspace DB shape PLUS an empty right panel in the UI. After restart, similar DB shape but UI is fine.

Implication: the failure may be in Glass render/binding lifecycle (or a missing layout cache — I see repeated `LayoutStateModel.load detected missing workspace layout cache` in Cursor Structured Logs on workspace open), not simply `editorPanelVisibility.visible=false` in global state.

I will run the same dump again next time the UI breaks (before restart) and post a broken vs healthy pair. Script: dump `glass/cursor.editorPanelVisibility.agent/*` from globalStorage/state.vscdb plus workspace keys `cursor/agentLayout.panelVisible`, `terminal`, `terminal.integrated.layoutInfo`.

Just reproduced again (~2 min after restart baseline). This is the **wrong-terminal-bound** variant.

**Repro (just now):**

1. Had (web3sec) general and (MAIN) hermes both with running terminals, swapping fine.

2. Switched away, then clicked back to **(MAIN) hermes** in sidebar.

3. Right panel initially showed **Changes**, not Terminal.

4. Clicked Terminal tab in the right panel header.

5. Terminal list shows **2 terminals: `web3sec` + empty `powershell`** — but selected sidebar chat is **(MAIN) hermes**.

6. The hermes terminal that was running before is gone. Wrong chat’s terminal is showing instead.

Screenshot: Screenshot - 349e14102cf3d7f3f6baad57894685d5 - Gyazo

**State dump taken while bug is active (UI wrong, 2026-06-21 00:49 UTC):**

```

GLOBAL web3sec: editorPanelVisibility.visible = true (updated 00:48:44)

GLOBAL hermes: editorPanelVisibility.visible = true (updated 00:48:39)

WORKSPACE hermes (selected chat):

cursor/agentLayout.panelVisible = false

terminal.isHidden = true

terminal.integrated.layoutInfo.tabs = [] # no tabs registered for hermes workspace

terminal.numberOfVisibleViews = 1 # but UI shows 2 terminals incl web3sec

```

So the UI is showing a **web3sec-named terminal while hermes composer is selected**, and workspace DB has **zero terminal tabs** for hermes. Looks like Glass is rendering a stale/wrong terminal from another composer instead of restoring the bound one.

Compare to healthy baseline from post #7 ~6 min earlier: same workspace DB shape but UI was correct. So the DB alone doesn’t predict the bug — something in the Glass terminal switch/render path is losing the per-composer binding.

Thanks for the detailed follow-ups. The state dumps, screenshot, and the broken vs healthy comparison really help.

The crossed terminal identity case, where the selected chat shows the terminal from another composer, is a new and useful signal. I added it to the internal issue along with your data: visible: true in global state while the panel is empty, LayoutStateModel.load detected missing workspace layout cache in Structured Logs, and terminal.integrated.layoutInfo.tabs = [] for the affected workspace. The fact that the workspace SQLite looks the same in both the broken and healthy state is noted too. That points more to the Glass render or binding lifecycle, not just a visibility flag.

If you can, please grab that broken vs healthy pair of dumps you mentioned, using the same composer ID before and after the panel breaks. Also, if you catch it, a short screencast of the transition where the terminal disappears or gets swapped would be great. That’s the best way to help us move toward a reliable repro on our side.

I can’t share an ETA for a fix yet, but if there’s an update, I’ll reply in the thread.

Thanks Dean — the broken vs healthy pair is already in the thread from the same session (~6 min apart, same composer IDs). Collating it here in one place for the internal issue.

**Composer IDs (stable across both dumps):**

- hermes (MAIN): `c824a66a-8c59-4815-995e-2e852b5a5f8c`

- web3sec (general): `c26e779c-10c8-44b8-9750-c2219ddd3ca2`

-–

**HEALTHY — post #7, 2026-06-21 ~00:43 UTC**

UI: both chats have terminals, swapping back and forth works.

```

GLOBAL hermes (c824a66a):

editorPanelVisibility.visible = true

WORKSPACE hermes (9ff23b98…):

cursor/agentLayout.panelVisible = false

terminal.isHidden = true

terminal.integrated.layoutInfo.tabs = []

workbench.panel.hidden = true

```

-–

**BROKEN — post #8, 2026-06-21 ~00:49 UTC (same composers, ~6 min later)**

UI: selected (MAIN) hermes, but terminal list shows web3sec + empty powershell. Hermes terminal gone.

Screenshot: Screenshot - 349e14102cf3d7f3f6baad57894685d5 - Gyazo

```

GLOBAL hermes (c824a66a):

editorPanelVisibility.visible = true (updated 00:48:39)

WORKSPACE hermes (9ff23b98…):

cursor/agentLayout.panelVisible = false

terminal.isHidden = true

terminal.integrated.layoutInfo.tabs = []

terminal.numberOfVisibleViews = 1 # UI showed 2 terminals incl web3sec

```

-–

**Takeaway:** workspace SQLite is effectively identical healthy vs broken. Global editorPanelVisibility stays true. The only change is what Glass renders — wrong terminal bound, or panel on Changes tab instead of Terminal. That matches your render/binding lifecycle theory.

**Structured log (repeated on workspace open):**

`LayoutStateModel.load detected missing workspace layout cache`

Path: %APPDATA%\Cursor\logs\\window*\exthost\anysphere.cursor-always-local\Cursor Structured Logs.workspaceId-9ff23b98…log

**Screencast:** didn’t capture the transition live — bug is intermittent and the swap happens on a single sidebar click. I have the Gyazo end-state screenshot (post #8). Next time it happens I’ll try Win+Alt+R before touching anything else to catch the click → Changes tab → wrong terminal sequence.

**Dump script** (run before restart when UI breaks):

`python agents/web3sec/runs/cursor-terminal-state-dump.py broken`

Reads global `glass/cursor.editorPanelVisibility.agent/{composerId}` + workspace `cursor/agentLayout.panelVisible`, `terminal`, `terminal.integrated.layoutInfo`.

Thanks for putting the broken vs healthy pair together in one place, it’s way easier to work with internally.

The main takeaway matches what we suspected: the workspace SQLite is basically the same in both states, the global editorPanelVisibility.visible stays true, and the only thing that actually changes is what Glass renders (someone else’s terminal in the binding, or the Changes panel instead of Terminal). That points to a render or binding lifecycle issue, not a visibility flag. I also added the stable composer IDs and LayoutStateModel.load detected missing workspace layout cache from Structured Logs to the issue.

A screencast of the actual transition (click → Changes tab → someone else’s terminal) would still be helpful if you can catch it with Win+Alt+R before you touch anything else. That’s the best chance for us to turn this into a stable repro.

I can’t share an ETA for a fix yet, but if there’s an update, I’ll reply in the thread.

I’m having a similar issue:

Title: Glass/Agents layout: Browser panel disappears or switches away when changing chats

Category: Bug Reports → Agents Window / Layout


Where does the bug appear?

Cursor IDE — Glass / Agents Window

Describe the Bug

In Glass (Agents Window), I keep the Browser panel open on the right (previewing localhost:1985 prototypes). When I switch chats in the left sidebar or start a new chat, the Browser panel is often removed entirely or replaced with another right-panel tab (e.g. Changes). The chat history loads fine; only the per-conversation right-panel state fails to restore.

This appears to be the same class of issue as the terminal panel regression in this thread, but affecting the Browser tab specifically.

Observed symptoms:

  • Browser panel vanishes after switching chats
  • Right panel jumps to Changes (or another tab) instead of Browser
  • Happens when creating a new chat, not only when switching existing ones
  • Intermittent but frequent enough to block multi-chat prototype workflows

Steps to Reproduce

  1. Open Cursor in Glass/Agents mode (cursor/firstWindowOpenGlassTreatment: true on my machine).
  2. Open workspace proto-plugin (/Users/maayanalbert/Documents/proto-plugin).
  3. Start an agent chat; open the Browser panel on the right and navigate to a prototype (e.g. http://localhost:1985/prototypes/event-types).
  4. Start a second agent chat (or switch to an existing one) via the left sidebar.
  5. Switch back to the first chat, or continue switching between chats.

Observed: Browser panel is gone or a different right-panel tab is shown. Chat/conversation UI remains.

Expected Behavior

Re-selecting an agent chat should restore that chat’s right-panel layout — including which tab was active (Browser) and the browser view — the same way per-chat terminal state is intended to work.

Operating System

macOS (darwin 25.5.0, arm64)

Version Information

  • Cursor: 3.10.17 (stable)
  • Layout: Glass/Agents Window, sidebar left
  • Workspace ID: 2278f50ce82d4f3bdce8ff4ed65d0825 (proto-plugin)

Additional Information

Local state evidence (captured 2026-07-06):

Per-composer panel visibility is stored in globalStorage/state.vscdb under keys like glass/cursor.editorPanelVisibility.agent/{composerId}:

Total keys: 597

visible: true → 536

visible: false → 65

Sample value: {“visible”:true,“updatedAtMs”:1783386050752}

Recent composers with visible: true (panel should be shown):

  • c5c67a90-052c-4b14-99b1-edf3089a7e44
  • 48927a79-8e96-4be6-b6aa-d73f1d21a187
  • 1ac577c2-59bb-4594-a3e1-f8445fb9357e

Layout geometry is stored in a shared global key (not per-composer):

agentLayout.shared.v6 = {“auxiliaryBarVisible”:false,“panelVisible”:true,“sidebarVisible”:false,…}

Workspace-level state (workspaceStorage/2278f50ce82d4f3bdce8ff4ed65d0825/state.vscdb):

cursor/agentLayout.panelVisible = true

terminal.isHidden = true

workbench.panel.hidden = false

Hypothesis: Per-composer editorPanelVisibility.visible says the panel should be visible, but Glass’s render/binding lifecycle fails to restore the correct right-panel tab (Browser) on chat switch — similar to the terminal desync described in the linked thread.

Structured logs: On prior workspace opens I have seen:

LayoutStateModel.load detected missing workspace layout cache

(e.g. Cursor Structured Logs.workspaceId-2278f50ce82d4f3bdce8ff4ed65d0825.*.log)

Browser MCP registry (healthy at time of report — separate from this bug):

  • 2 active glass-browser-* tabs on localhost:1985
  • No phantom/orphan tab handles

Related thread: Per-chat terminal panel missing after switching sidebar conversations — Cursor staff filed an internal issue for render/binding lifecycle failures with visible: true in global state while the panel is empty or wrong.

Workarounds tried:

  • Re-clicking Browser in the right panel header (sometimes works, often doesn’t)
  • Cmd+Shift+M full-screen browser (helps stay on page but doesn’t fix restore on switch)
  • External browser for localhost (only reliable workaround)

Happy to provide a broken vs healthy state dump pair and a screen recording of the sidebar click → panel gone transition if that helps reproduce.

Does this stop you from using Cursor?

Sometimes — I can use Cursor, but multi-chat agent + browser preview workflows are unreliable.


Shorter version (Help → Report Bug)

Summary: Browser panel in Glass disappears or switches to another tab when I change chats or start a new chat.

Steps:

  1. Glass/Agents mode, Browser open on right (localhost:1985)
  2. Switch chats in left sidebar or create new chat
  3. Browser panel gone or wrong tab shown; chat history intact

Expected: Each chat restores its Browser panel state on switch.

Actual: Panel removed or replaced (often Changes).

Environment: macOS arm64, Cursor 3.10.17, workspace proto-plugin (2278f50ce82d4f3bdce8ff4ed65d0825).

Evidence: 597 glass/cursor.editorPanelVisibility.agent/{composerId} keys in global state (536 visible: true); shared agentLayout.shared.v6 layout; likely same render/binding bug as forum thread 163709 but for Browser tab.

Impact: Blocks keeping a prototype preview visible while hopping between agent chats.


Capture script (run when the bug happens)

Save this and run it while the UI is broken, before restarting Cursor. Cursor staff specifically asked for broken vs healthy pairs.

#!/usr/bin/env bash

# cursor-glass-panel-dump.sh [broken|healthy]

LABEL=“${1:-snapshot}”

TS=$(date -u +%Y%m%dT%H%M%SZ)

OUT=“$HOME/Desktop/cursor-glass-panel-$LABEL-$TS.txt”

GLOBAL=“$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb”

WS=“$HOME/Library/Application Support/Cursor/User/workspaceStorage/2278f50ce82d4f3bdce8ff4ed65d0825/state.vscdb”

{

echo “label=$LABEL captured=$TS”

echo “cursor_version=$(defaults read /Applications/Cursor.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null)”

echo

echo “=== GLOBAL: editorPanelVisibility counts ===”

sqlite3 “$GLOBAL” “SELECT json_extract(value,‘$.visible’), COUNT(*) FROM ItemTable WHERE key LIKE ‘glass/cursor.editorPanelVisibility.agent/%’ GROUP BY 1;”

echo

echo “=== GLOBAL: 5 most recent visible=true ===”

sqlite3 “$GLOBAL” “SELECT key, value FROM ItemTable WHERE key LIKE ‘glass/cursor.editorPanelVisibility.agent/%’ AND json_extract(value,‘$.visible’)=1 ORDER BY json_extract(value,‘$.updatedAtMs’) DESC LIMIT 5;”

echo

echo “=== GLOBAL: agentLayout.shared.v6 ===”

sqlite3 “$GLOBAL” “SELECT value FROM ItemTable WHERE key=‘agentLayout.shared.v6’;”

echo

echo “=== WORKSPACE proto-plugin ===”

sqlite3 “$WS” “SELECT key, value FROM ItemTable WHERE key IN (‘cursor/agentLayout.panelVisible’,‘terminal’,‘terminal.integrated.layoutInfo’,‘workbench.panel.hidden’);”

} > “$OUT”

echo “Wrote $OUT”

Usage:

chmod +x ~/Desktop/cursor-glass-panel-dump.sh

~/Desktop/cursor-glass-panel-dump.sh broken # when panel is gone

~/Desktop/cursor-glass-panel-dump.sh healthy # after you reopen Browser manually

Hey, thanks for the detailed report, and especially for the state-dump pair, the script, and the breakdown of the editorPanelVisibility.agent/{composerId} keys. That’s super helpful.

You’re right that it’s the same class of issue (render or binding when switching chats in the Agents Window), but it’s basically a separate variant. This thread is about the terminal panel, and in your case the Browser tab disappears or switches. To avoid mixing data and to track the Browser variant properly, please create a separate thread for it in Bug Reports. Feel free to reuse what you already wrote, it’s great.

In the new thread, please include if you can:

  • A broken vs healthy pair of dumps for the same composer ID, before and after the panel breaks, like you already did for the terminal.
  • A short screencast of the transition, click in the sidebar then Browser disappears or switches to Changes. On macOS it’s easy to record with Cmd+Shift+5. This is the best chance for us to get a stable repro.

Once the thread is up, I’ll link it to the right internal issue. I can’t share an ETA for a fix yet, but I’ll follow up if there’s an update.

Where does the bug appear (feature/product)?

Somewhere else…

Describe the Bug

Agent Window

I’m on Windows and using the Agents Window. I work with a terminal with claude code in my agents, but when I have two or more agents from the same or different projects, sometimes I go to another agent and the terminals get reloaded and I lose my CC session or any other process that was running on it.

Steps to Reproduce

  1. Open 2 or more agents
  2. Open a terminal on each agent
  3. Trigger a long running process on each terminal
  4. Jump between agents, at some point you will see that any of the agents get its terminals reloaded.

Expected Behavior

Terminal session should not get reloaded when jumping between agents.

Operating System

Windows 10/11

Version Information

Version: 3.10.20 (user setup)
VS Code Extension API: 1.125.0
Commit: 23b9fb205fe595ea2be29da7214e19762d037fc0
Date: 2026-07-07T07:03:33.071Z
Layout: Agent Window
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

Additional Information

I’m using Powershell 7 and Windows Terminal

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Same regression here, and I think I can add a concrete log signature that pins down the mechanism.

Environment

  • Cursor 3.12.17 (macOS, darwin 25.5.0), auto-updated on 2026-07-17

  • Worked fine before the recent 3.12.x updates; broke after this build

  • Layout: multiple projects/folders in one Agents window, switching left<->right in the sidebar (each project has its own bound terminal)

Symptom
Terminals I leave behind when switching to another project get killed ~1 minute after the switch — including long-running foreground processes (e.g. an interactive CLI). I never close a window or a terminal; I only switch projects within the same window.

Log signature (this is the key part)
The kill is not an OS/OOM kill and not a crash. It’s Cursor’s normal pty grace-GC firing because the terminal is never re-bound on project switch.

ptyhost.log:

[warning] Couldn't get layout info, a terminal was probably disconnected: Could not find pty 30 on pty host
[info] Persistent process "30": The reconnection grace time of 1m has expired, shutting down pid "62405"

And it correlates exactly (+1 min) with a clean Extension host exit in main.log on every project switch:

main.log    09:55:51  Extension host ... exited with code: 0, signal: unknown
ptyhost.log 09:56:51  Persistent process "29": grace time of 1m expired, shutting down pid 57924

main.log    10:01:56  Extension host ... exited with code: 0, signal: unknown
ptyhost.log 10:02:56  Persistent process "30"/"31": grace expired, shutting down pid 62405/62890

Interpretation
exited with code: 0 = clean teardown of the previous project’s workspace on switch, not a crash. Previously the terminal panel was re-bound/reconnected within the grace window when switching projects, so the shell survived. Since 3.12.x the per-project terminal binding is no longer restored on sidebar switch, so from the pty host’s view the terminal stays disconnected → the standard 1-minute reconnection grace expires → shutting down pid. The grace/GC itself is correct; the missing piece is the rebind on project switch.

Repro

  1. Open >=2 projects/folders in one Agents window.

  2. Start a terminal in project A (ideally a long-running foreground process).

  3. Switch to project B and stay there for >1 minute.

  4. Switch back to A → terminal is gone; ptyhost.log shows the “grace time of 1m expired, shutting down pid” line ~1 min after the switch.

Happy to provide full ptyhost.log/main.log excerpts if useful.

Hey, thanks for the report, and extra thanks for the log signature, it’s really valuable. The Extension host ... exited with code: 0 in main.log lining up exactly one minute later with reconnection grace time of 1m has expired in ptyhost.log matches what we’re already seeing. When switching projects, the per-project terminal doesn’t rebind within the grace window, the pty host treats it as disconnected, and the normal 1-minute GC shuts the process down. So the GC itself is working as intended, the problem is the missing rebind on project switch.

This is the same class of bug we’re already tracking in that thread. I added your 3.12.17 / macOS case to the internal issue. It’s helpful since it expands the affected version range. I can’t share an ETA for a fix yet, but I’ll post here if there’s an update.

Please also send the full ptyhost.log and main.log excerpts you offered, they won’t be redundant. If you can capture the exact moment it flips into that state click in the sidebar then the terminal disappears, that would also help a lot with reproducing it on our side.

Thanks Dean, much appreciated. Full excerpts below.

Environment

  • Cursor 3.12.17, macOS (darwin 25.5.0)

  • Auto-update timeline (from main.log): downloaded/“ready” on 2026-07-13, 2026-07-16, 2026-07-19/20; the installed app binary was replaced 2026-07-17. The behavior was fine on the build before this range.

  • The IDs like 1a295dd0... / 5956b638... are terminal-instance IDs, not secrets.

1) Exact +1:00 correlation (2026-07-21, single day)

Every clean Extension host ... exited with code: 0 in main.log is followed exactly one minute later by a grace time of 1m has expired, shutting down pid in ptyhost.log. Each pair is a project switch in the sidebar.

main.log    08:35:08.570  Extension host with pid 53213 exited with code: 0, signal: unknown
ptyhost.log 08:36:08.736  Persistent process "25": grace time of 1m expired, shutting down pid 67253
ptyhost.log 08:36:08.737  Persistent process "26": grace time of 1m expired, shutting down pid 68917

main.log    08:43:14.564  Extension host with pid 53539 exited with code: 0, signal: unknown
ptyhost.log 08:44:14.744  Persistent process "27": grace time of 1m expired, shutting down pid 53714

main.log    09:12:09.567  Extension host with pid 55097 exited with code: 0, signal: unknown
ptyhost.log 09:13:09.715  Persistent process "28": grace time of 1m expired, shutting down pid 55126

main.log    09:55:51.556  Extension host with pid 57891 exited with code: 0, signal: unknown
ptyhost.log 09:56:51.682  Persistent process "29": grace time of 1m expired, shutting down pid 57924

main.log    10:01:56.564  Extension host with pid 62277 exited with code: 0, signal: unknown
ptyhost.log 10:02:56.717  Persistent process "30": grace time of 1m expired, shutting down pid 62405
ptyhost.log 10:02:56.719  Persistent process "31": grace time of 1m expired, shutting down pid 62890

main.log    10:48:42.565  Extension host with pid 66263 exited with code: 0, signal: unknown
ptyhost.log 10:49:42.729  Persistent process "33": grace time of 1m expired, shutting down pid 66379

main.log    10:49:42.564  Extension host with pid 64064 exited with code: 0, signal: unknown
ptyhost.log 10:50:42.694  Persistent process "32": grace time of 1m expired, shutting down pid 64122

main.log    10:59:29.595  Extension host with pid 68823 exited with code: 0, signal: unknown
ptyhost.log 11:00:29.794  Persistent process "34": grace time of 1m expired, shutting down pid 68862

2) ptyhost.log — full excerpt (session 20260708T143649, 07-08 → 07-21)

2026-07-08 14:36:53.050 [warning] Persistent process "3": Process had no disconnect runners but was an orphan
2026-07-08 14:36:53.050 [info] Persistent process reconnection "3"
2026-07-08 14:36:53.069 [warning] Persistent process "1": Process had no disconnect runners but was an orphan
2026-07-08 14:36:53.072 [info] Persistent process reconnection "1"
2026-07-08 17:41:59.811 [info] Persistent process "6": The reconnection grace time of 1m has expired, shutting down pid "36588"
2026-07-09 08:54:58.222 [info] Persistent process "5": The reconnection grace time of 1m has expired, shutting down pid "35688"
2026-07-09 10:34:08.140 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 5 on pty host
2026-07-09 10:36:18.250 [info] Persistent process "7": The reconnection grace time of 1m has expired, shutting down pid "96752"
2026-07-09 13:52:29.684 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 7 on pty host
2026-07-09 13:54:30.302 [info] Persistent process "8": The reconnection grace time of 1m has expired, shutting down pid "3645"
2026-07-09 14:50:08.004 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 6 on pty host
2026-07-10 09:44:46.441 [info] Persistent process "9": The reconnection grace time of 1m has expired, shutting down pid "19492"
2026-07-10 09:44:46.443 [info] Persistent process "10": The reconnection grace time of 1m has expired, shutting down pid "19916"
2026-07-10 09:44:54.092 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 8 on pty host
2026-07-10 10:50:43.409 [info] Persistent process "12": The reconnection grace time of 1m has expired, shutting down pid "55585"
2026-07-10 10:50:43.411 [info] Persistent process "13": The reconnection grace time of 1m has expired, shutting down pid "59062"
2026-07-10 18:10:56.738 [info] Persistent process "11": The reconnection grace time of 1m has expired, shutting down pid "55235"
2026-07-10 22:15:06.423 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 9 on pty host
2026-07-10 22:15:06.423 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 10 on pty host
2026-07-12 19:24:49.322 [info] Persistent process "14": The reconnection grace time of 1m has expired, shutting down pid "2337"
2026-07-12 19:55:29.434 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 12 on pty host
2026-07-12 19:55:29.434 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 13 on pty host
2026-07-12 19:55:34.046 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 14 on pty host
2026-07-13 08:06:23.636 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 11 on pty host
2026-07-13 08:08:32.007 [info] Persistent process "15": The reconnection grace time of 1m has expired, shutting down pid "52393"
2026-07-13 08:50:54.727 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 12 on pty host
2026-07-13 08:50:54.727 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 13 on pty host
2026-07-13 10:13:47.950 [info] Persistent process "16": The reconnection grace time of 1m has expired, shutting down pid "18552"
2026-07-13 10:13:47.951 [info] Persistent process "17": The reconnection grace time of 1m has expired, shutting down pid "28517"
2026-07-13 10:24:47.140 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 16 on pty host
2026-07-13 10:24:47.140 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 17 on pty host
2026-07-13 10:48:00.848 [info] Persistent process "18": The reconnection grace time of 1m has expired, shutting down pid "32872"
2026-07-13 13:25:04.397 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 18 on pty host
2026-07-13 16:01:30.066 [info] Persistent process "19": The reconnection grace time of 1m has expired, shutting down pid "50693"
2026-07-13 16:37:40.134 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 19 on pty host
2026-07-14 08:22:22.954 [info] Persistent process "20": The reconnection grace time of 1m has expired, shutting down pid "70886"
2026-07-14 08:23:03.973 [info] Persistent process "21": The reconnection grace time of 1m has expired, shutting down pid "99243"
2026-07-14 09:45:23.998 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 20 on pty host
2026-07-14 13:43:04.295 [info] Persistent process reconnection "3"
2026-07-14 13:43:05.663 [info] Persistent process reconnection "23"
2026-07-14 13:43:05.663 [info] Persistent process reconnection "22"
2026-07-14 16:32:13.558 [info] Persistent process "22": The reconnection grace time of 1m has expired, shutting down pid "13423"
2026-07-14 16:32:13.562 [info] Persistent process "23": The reconnection grace time of 1m has expired, shutting down pid "27543"
2026-07-14 16:56:04.164 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 21 on pty host
2026-07-15 08:17:11.770 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 22 on pty host
2026-07-15 08:17:11.770 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 23 on pty host
2026-07-15 08:18:27.880 [info] Persistent process "24": The reconnection grace time of 1m has expired, shutting down pid "59733"
2026-07-21 08:36:08.736 [info] Persistent process "25": The reconnection grace time of 1m has expired, shutting down pid "67253"
2026-07-21 08:36:08.737 [info] Persistent process "26": The reconnection grace time of 1m has expired, shutting down pid "68917"
2026-07-21 08:42:07.458 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 25 on pty host
2026-07-21 08:42:07.458 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 26 on pty host
2026-07-21 08:44:14.744 [info] Persistent process "27": The reconnection grace time of 1m has expired, shutting down pid "53714"
2026-07-21 09:10:57.186 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 24 on pty host
2026-07-21 09:13:09.715 [info] Persistent process "28": The reconnection grace time of 1m has expired, shutting down pid "55126"
2026-07-21 09:54:51.101 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 28 on pty host
2026-07-21 09:56:51.682 [info] Persistent process "29": The reconnection grace time of 1m has expired, shutting down pid "57924"
2026-07-21 10:00:42.944 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 29 on pty host
2026-07-21 10:02:56.717 [info] Persistent process "30": The reconnection grace time of 1m has expired, shutting down pid "62405"
2026-07-21 10:02:56.719 [info] Persistent process "31": The reconnection grace time of 1m has expired, shutting down pid "62890"
2026-07-21 10:24:28.520 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 30 on pty host
2026-07-21 10:24:28.521 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 31 on pty host
2026-07-21 10:48:41.450 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 27 on pty host
2026-07-21 10:49:42.729 [info] Persistent process "33": The reconnection grace time of 1m has expired, shutting down pid "66379"
2026-07-21 10:50:42.694 [info] Persistent process "32": The reconnection grace time of 1m has expired, shutting down pid "64122"
2026-07-21 10:58:14.806 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 32 on pty host
2026-07-21 11:00:29.794 [info] Persistent process "34": The reconnection grace time of 1m has expired, shutting down pid "68862"

3) ptyhost.log — full excerpt (session 20260721T110133, 07-21 → 07-22)

Note the Expanding terminal instance ... -> new id undefined right before the “Could not find pty” line — that is the switch not resolving to a live pty.

2026-07-21 11:01:37.233 [info] Revived process, old id 1a295dd0d5965ab58d020d479e5db38b-1 -> new id 1
2026-07-21 11:01:37.393 [warning] Persistent process "1": Process had no disconnect runners but was an orphan
2026-07-21 11:01:37.393 [info] Persistent process reconnection "1"
2026-07-21 11:01:37.503 [info] Persistent process "1": Replaying 757 chars and 1 size events
2026-07-21 11:01:37.623 [warning] Persistent process "2": Process had no disconnect runners but was an orphan
2026-07-21 11:01:37.624 [info] Persistent process reconnection "2"
2026-07-21 11:01:38.892 [warning] Persistent process "3": Process had no disconnect runners but was an orphan
2026-07-21 11:01:38.896 [info] Persistent process reconnection "3"
2026-07-21 11:05:33.090 [info] Expanding terminal instance, old id 5956b638cac229362d053cf46f4c37d2-3 -> new id undefined
2026-07-21 11:05:33.731 [info] Persistent process reconnection "3"
2026-07-21 11:07:39.447 [info] Persistent process "4": The reconnection grace time of 1m has expired, shutting down pid "72803"
2026-07-21 11:23:36.831 [info] Expanding terminal instance, old id 9739919f9fe08eacd852b0a89325fe10-4 -> new id undefined
2026-07-21 11:23:36.831 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 4 on pty host
2026-07-21 11:24:39.537 [info] Persistent process "5": The reconnection grace time of 1m has expired, shutting down pid "73378"
2026-07-21 11:25:39.459 [info] Persistent process "3": The reconnection grace time of 1m has expired, shutting down pid "71436"
2026-07-21 13:46:41.171 [info] Expanding terminal instance, old id 5956b638cac229362d053cf46f4c37d2-3 -> new id undefined
2026-07-21 13:46:41.171 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 3 on pty host
2026-07-21 14:24:54.996 [info] Expanding terminal instance, old id 4b2c3c36e60b4d695aaf3873f5192dc7-5 -> new id undefined
2026-07-21 14:24:54.996 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 5 on pty host
2026-07-21 14:26:56.457 [info] Persistent process "7": The reconnection grace time of 1m has expired, shutting down pid "87214"
2026-07-21 14:57:58.490 [info] Persistent process "8": The reconnection grace time of 1m has expired, shutting down pid "91237"
2026-07-22 09:24:49.572 [info] Expanding terminal instance, old id 5956b638cac229362d053cf46f4c37d2-7 -> new id undefined
2026-07-22 09:24:49.572 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 7 on pty host
2026-07-22 09:29:06.320 [info] Persistent process "6": The reconnection grace time of 1m has expired, shutting down pid "77191"
2026-07-22 09:29:06.321 [info] Persistent process "9": The reconnection grace time of 1m has expired, shutting down pid "95068"
2026-07-22 10:16:55.228 [info] Expanding terminal instance, old id 9739919f9fe08eacd852b0a89325fe10-6 -> new id undefined
2026-07-22 10:16:55.229 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 6 on pty host
2026-07-22 10:16:55.229 [info] Expanding terminal instance, old id 9739919f9fe08eacd852b0a89325fe10-9 -> new id undefined
2026-07-22 10:16:55.229 [warning] Couldn't get layout info, a terminal was probably disconnected Could not find pty 9 on pty host

4) main.log — the matching Extension host exits (2026-07-21)

2026-07-21 08:35:08.570  Extension host with pid 53213 exited with code: 0, signal: unknown
2026-07-21 08:43:14.564  Extension host with pid 53539 exited with code: 0, signal: unknown
2026-07-21 09:12:09.567  Extension host with pid 55097 exited with code: 0, signal: unknown
2026-07-21 09:44:22.617  Extension host with pid 53212 exited with code: 0, signal: unknown
2026-07-21 09:55:51.556  Extension host with pid 57891 exited with code: 0, signal: unknown
2026-07-21 10:01:56.564  Extension host with pid 62277 exited with code: 0, signal: unknown
2026-07-21 10:48:42.565  Extension host with pid 66263 exited with code: 0, signal: unknown
2026-07-21 10:49:42.564  Extension host with pid 64064 exited with code: 0, signal: unknown
2026-07-21 10:59:29.595  Extension host with pid 68823 exited with code: 0, signal: unknown

5) The moment it flips (what I see in the UI vs the log)

When I click a different project in the sidebar, ptyhost logs Expanding terminal instance, old id <workspaceHash>-<n> -> new id undefined immediately, followed by Could not find pty <n> on pty host. The -> new id undefined is the tell: on switch the terminal instance is not resolved/rebound to its live pty. The panel then shows empty, and ~1 min later the shell is GC’d. Switching back within that minute occasionally restores it (see the Persistent process reconnection lines); staying away >1 min always loses it.

Happy to send the raw files or capture a screen recording of the sidebar click → empty panel → log line if that helps.

Thanks for the full logs, Simon, that’s exactly what we need. The key signal is Expanding terminal instance, old id <hash>-<n> -> new id undefined right before Could not find pty <n>. That confirms that when switching projects, the terminal doesn’t resolve to a live pty, then the normal 1-minute reconnection grace period runs and the process goes into shutting down pid. The exact +1:00 correlation between the clean Extension host ... exited with code: 0 in main.log and the GC in ptyhost.log confirms this. The GC is working as intended, the issue is the missing rebind on switch.

This is the same class of bug already described in this thread. Your case on 3.12.17 on macOS was added to the internal issue. It expands the range of affected versions, so it’s helpful.

I can’t give an ETA on a fix yet, but if there’s an update, I’ll post it here. If you can capture a short screencast of the transition click in the sidebar, then an empty panel, then the log line, that’d still help, but you’ve already provided more than enough data.

I just posted an issue for this, but it looks like it is being tracked. Glad to see that. Sorry to bother, but any updates @deanrie ?

Hey, thanks for checking in here. There’s no timeline update yet. The issue is on our radar and we’ve confirmed the behavior: the terminal doesn’t rebind when switching between chats or projects, and after the 1-minute grace period the pty gets garbage collected. I can’t share an ETA, but as soon as there’s anything new I’ll reply in this thread.

You mentioned you started a separate thread. Please send the link so I can tie it to the same internal issue and make sure your case doesn’t get lost.

If you can add a bit more context, that’d help a lot: your Cursor version, OS, and if you catch it happening, a short screencast showing click in sidebar → empty panel, plus lines from ptyhost.log and main.log around grace time of 1m expired. That’s not required, but it helps us get a stable repro on our side.

As a temporary workaround, a full Cursor restart restores things. For critical long-running processes, it’s more reliable to switch back to the chat within the 1-minute window, switching back within a minute sometimes reconnects the terminal.