Skip to content

Completed worktree sessions leave Copilot CLI processes and stale background activity on Windows #3151

Description

@chboeye

Summary

On Windows, completed worktree-backed sessions can leave their per-session copilot.exe --server --stdio process running after the PR is merged and the worktree directory has already been cleaned. The process retains a worktree handle, can make archival fail with Windows os error 32, and Background activity can show checks as running when no agent or test process exists.

Reproduced across three independent completed sessions and during a larger child-session cleanup.

Environment

  • GitHub Copilot App 1.1.12
  • Agency 2026.8.21.9
  • Copilot CLI 1.0.80
  • Windows 11 Enterprise Insider Preview 10.0.29648 (build 29648)
  • Local worktree-backed sessions
  • Observed 2026-08-24/25

Evidence

Three sessions had merged PRs whose exact heads were ancestors of origin/master. Their worktree directories existed but had zero entries and no .git. Each still had one Copilot CLI server referencing the removed worktree:

<LOCAL_APP_DATA>\github-copilot-sdk\cli\1.0.80\copilot.exe
  --server --stdio --add-dir <WORKTREE_PATH> ...

Residual PIDs observed: 86828, 134332, 139508 (ephemeral, for correlation only).

An archive attempt also failed repeatedly with:

Failed to archive session: The process cannot access the file because it is being used by another process. (os error 32)

Sysinternals Handle identified:

github.exe   pid 61856   File handle 1C08   <WORKTREE_PATH>
copilot.exe  pid 144316  File handle 5C     <WORKTREE_PATH>

After stopping only PID 144316, the app released its handle and the same archive operation succeeded. Sequential archival then succeeded for every session. The process did not respawn.

The app also showed these as active:

Run full exact-SHA local gate
Run exact-SHA fabricated browser proof

Independent inspection showed zero running agents, only an idle Scribe, all shell tasks completed, and no matching Node/npm/Playwright/browser-test process.

Log evidence

Raw logs are not attached because they contain local paths, MCP metadata, and conversation/tool payloads. Redacted inventory:

Case Agency log Copilot process log
Completed A 484,099 B 69,644,142 B
Completed B 343,884 B 24,139,171 B
Completed C 454,435 B 131,400,825 B
Archive lock 95,181 B 985,924 B

Each completed-session Agency log records Working directory, Adding git root to --add-dir, and Executing copilot command with --server --stdio --add-dir <WORKTREE>. No corresponding shutdown, EOF, process-exit, or termination event was found. Logs end with periodic activity:

telem periodic flush: queue empty, nothing to commit
accepted OTLP signal (not yet processed) signal=/v1/metrics

One affected log contains repeated archive_session traces but no matching CLI shutdown.

Reproduction

  1. Create a local worktree-backed session on Windows.
  2. Complete work and merge its PR.
  3. Allow the app to clean the worktree while the session record remains visible.
  4. Inspect copilot.exe command lines for --server --stdio --add-dir <WORKTREE>.
  5. Attempt to archive the session, especially with other sessions.
  6. Observe os error 32 or a retained process/handle.
  7. Stop the exact per-session Copilot PID and retry; archival succeeds.

Expected

  • Archive terminates and awaits the per-session CLI, releases handles, removes the worktree, then marks the session archived atomically.
  • Completed background tasks leave the running section even if a worker exits unexpectedly.
  • If retaining an unarchived runtime is intentional, show it as idle and ensure archive closes it reliably.

Actual

  • Completed/merged sessions can retain a Copilot CLI indefinitely.
  • The CLI and GitHub App can retain worktree directory handles.
  • Archive can fail on its own retained handles with os error 32.
  • Background activity can show running tasks with no corresponding agent or OS process.

Workaround

Find the exact process associated with the worktree and stop only that PID, then archive sequentially:

Stop-Process -Id <EXACT_COPILOT_PID>

Do not terminate all processes by name because other sessions use the same executable.

All user paths, repository details, plugin IDs, MCP filenames, and conversation content are redacted. Full logs can be provided through a private diagnostic channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions