anthropics / anthropics/claude-code

[BUG] Desktop (Windows): shell PTYs started on session warm are not stopped when the session is paused by idle timeout; preview lifecycle opens a second PTY per session

Open
#93,151 0 comments 0 reactions 0 assignees View on GitHub
area:desktop bug has repro platform:windows
Dominant language
Python
Stars
145k
Forks
23.1k
PR merge metrics
PR metrics pending

Description

## What's Wrong?

When a session is warmed, the app calls `LocalSessions.startShellPty` and spawns a `powershell.exe` (+ a headless `conhost.exe`) for the session's Terminal panel. When the session is later paused by the 900 s idle timeout (`[CCD] Pausing session … (idle_timeout)`), the CLI and its MCP servers exit but the PTY shell is left running.

Today 10 sessions were warmed at 11:51 and paused between 12:06 and 12:08. At 12:14 all 10 `powershell.exe` PTYs were still alive (parent = the app's `NodeService` utility process, ~70 MB each, ~700 MB total plus 10 conhosts). Most disappeared only around the 1800 s preview timeout; 3 of the 10 were still alive 40 minutes after launch, long after their sessions had been paused.

Additionally, when the user returns to an already-warm session, `[WarmLifecycle:preview] Warming up session X` fires and a **second** `startShellPty` is issued for the same session (seen for 4 sessions), so a session can hold two shells.

## What Should Happen?

- `pauseSession(…, "idle_timeout")` (and `governor_evict`) should also call `stopShellPty` for that session, or the PTY should be started lazily when the Terminal panel is actually opened, not at warm time.
- Re-warming a session that already has a live PTY should reuse it rather than starting another.

## Error Messages/Logs

`%LOCALAPPDATA%\Claude\logs\main.log`:

```
11:51:01 [CCD] Warming session local_c28c…
11:51:02 LocalSessions.startShellPty: sessionId=local_c28c…, cols=80, rows=24
11:51:29 [WarmLifecycle:preview] Warming up session local_c28c…
11:51:29 LocalSessions.startShellPty: sessionId=local_c28c…, cols=80, rows=24 <- second PTY, same session
...
12:07:42 [WarmLifecycle:session] Idle timeout reached, disconnecting local_c28c…
12:07:42 [CCD] Pausing session local_c28c… (idle_timeout) <- no stopShellPty follows
```

Process list at 12:14 (parent 26464 = `Claude.exe --type=utility --utility-sub-type=node.mojom.NodeService`):

```
PID PPID Name WS_MB Started CommandLine
10704 26464 powershell.exe 70.0 11:51:15 C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe
10804 26464 powershell.exe 69.7 11:51:10 (same)
12220 26464 powershell.exe 69.8 11:52:24 (same)
12732 26464 powershell.exe 69.6 11:51:04 (same)
17928 26464 powershell.exe 69.6 11:51:29 (same)
20168 26464 powershell.exe 69.9 11:54:16 (same)
22864 26464 powershell.exe 69.8 11:52:52 (same)
25668 26464 powershell.exe 70.4 11:51:20 (same)
26944 26464 powershell.exe 69.6 11:51:21 (same)
```

Each has a matching `conhost.exe --headless --width 80 --height 24` child (~9 MB).

## Steps to Reproduce

1. Windows 11, Claude Desktop (MSIX), Code tab.
2. Click a few idle sessions in the sidebar so they warm; do not type anything.
3. Wait > 15 minutes for `Pausing session … (idle_timeout)` in main.log.
4. `Get-CimInstance Win32_Process -Filter "Name='powershell.exe'"` still shows one bare `powershell.exe` per warmed session, parented by the app's NodeService process.

## Claude Code Version

Desktop app 1.49585.0.0 (MSIX); bundled Claude Code 2.1.260.

## Platform

Claude.ai subscription (OAuth) via the desktop app.

## Operating System

Windows 11 Pro 10.0.26200.

## Terminal/Shell

Windows PowerShell 5.1 (the PTY the app spawns).

## Additional Information

Related: focusing a session (including archived ones) eagerly warms the full CLI + MCP stack (filed separately); the two together are what made the machine crawl.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by finding the lifecycle paths named in the logs: LocalSessions.startShellPty, stopShellPty, pauseSession with idle_timeout/governor_evict, and WarmLifecycle:preview. Reproduce on Windows 11 by warming sessions, waiting for idle pause, then checking powershell.exe with Get-CimInstance. Done means paused sessions do not retain PTYs and re-warming an already-warm session does not start a second shell.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, powershell
Domain
cli, desktop, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.