Summary
The Copilot CLI creates a ~/.copilot/session-state/<guid>/ folder for every session — including background automations, heartbeats, and memory-consolidation runs — and never prunes them. On a heavily-used machine these accumulate into the thousands. A Copilot component then bulk-opens session-state/*/workspace.yaml, exhausting the process's file-descriptor table (libuv's ~8189 limit on Windows) and throwing EMFILE: too many open files. In VS Code this makes Copilot Chat hang on "working" and crash after a few turns.
This is the root cause behind microsoft/vscode#313799 — that's where it manifests, but the fix belongs here.
Evidence (Windows, measured with Sysinternals handle.exe)
~/.copilot/session-state contained 10,313 workspace.yaml files, accumulated since 2026-02-18, never pruned.
- The Copilot
node.mojom.NodeService utility process peaked at ~8,788 open handles — right at the libuv fd ceiling — then dropped back to ~580 after the burst (which is why point-in-time snapshots look normal).
- In a single mid-spike handle dump, 3,256 of 3,352 (97%) File-handle paths were
session-state\...\workspace.yaml.
- Reducing the folder count to ~67 immediately resolved the EMFILE crashes.
Two underlying issues
- No retention/cleanup (primary): session-state folders grow unbounded — no age or count cap, no garbage collection.
- Unbounded fan-out open: the code that reads
workspace.yaml across sessions opens them without bounding concurrent file descriptors or closing promptly, so a large directory exhausts the fd table instead of degrading gracefully.
Suggested fixes
- Add automatic retention (e.g., prune session-state older than N days, or cap to the M most-recent) on CLI startup and/or via a background task.
- Bound concurrency and ensure prompt handle closure when enumerating session metadata.
- Optionally consolidate session metadata into a single index/DB rather than one folder + file per session.
Workaround
Periodically prune ~/.copilot/session-state (e.g., a scheduled task that deletes folders older than ~14 days).
Environment
Windows; GitHub Copilot CLI + VS Code Copilot Chat (stable).
Summary
The Copilot CLI creates a
~/.copilot/session-state/<guid>/folder for every session — including background automations, heartbeats, and memory-consolidation runs — and never prunes them. On a heavily-used machine these accumulate into the thousands. A Copilot component then bulk-openssession-state/*/workspace.yaml, exhausting the process's file-descriptor table (libuv's ~8189 limit on Windows) and throwingEMFILE: too many open files. In VS Code this makes Copilot Chat hang on "working" and crash after a few turns.This is the root cause behind microsoft/vscode#313799 — that's where it manifests, but the fix belongs here.
Evidence (Windows, measured with Sysinternals
handle.exe)~/.copilot/session-statecontained 10,313workspace.yamlfiles, accumulated since 2026-02-18, never pruned.node.mojom.NodeServiceutility process peaked at ~8,788 open handles — right at the libuv fd ceiling — then dropped back to ~580 after the burst (which is why point-in-time snapshots look normal).session-state\...\workspace.yaml.Two underlying issues
workspace.yamlacross sessions opens them without bounding concurrent file descriptors or closing promptly, so a large directory exhausts the fd table instead of degrading gracefully.Suggested fixes
Workaround
Periodically prune
~/.copilot/session-state(e.g., a scheduled task that deletes folders older than ~14 days).Environment
Windows; GitHub Copilot CLI + VS Code Copilot Chat (stable).