github / github/copilot-cli

Archiving a worktree session fails on Windows (os error 32): worktree is removed without stopping the session process tree rooted in it

オープン
#4,593 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

area:platform-windows area:sessions
主要言語
Shell
スター
11.2k
フォーク
1.9k
平均マージ
14時間 16分
マージ済み PR(30日)
6

説明

Describe the bug

On Windows, archiving/deleting a worktree-backed session fails with:

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

The archive is almost complete when it fails. By the time the error appears, the app has already emptied the worktree, removed its .git entry, and deregistered it from the parent repo. The only step left is the final rmdir — and that step can never succeed, because the app removes the worktree directory without first stopping the session process tree whose current directory is that same folder.

Windows refuses to remove a directory that is any live process's CWD. The app retries 5 times over ~5 seconds and gives up, but retrying cannot help here: the holder is alive by design and will still be alive on the next attempt. The result is a permanently un-archivable session and an orphaned empty folder.

From github-app.<pid>.log:

github_app::git::worktree: path still locked by another process after retrying removal
  path=C:\Users\<user>\.copilot\copilot-worktrees\<repo>\<session-branch> attempts=5
  error=The process cannot access the file because it is being used by another process. (os error 32)

github_app::workspace::handlers::lifecycle: failed to remove app-owned worktree
  worktree_path=... error=... (os error 32)
  initial_error=git ["fsmonitor--daemon", "stop"] failed: fatal: not a git repository (or any of the parent directories): .git
  retry_error=None

github_app::handlers::workspace: failed to archive workspace error=... (os error 32)

Note the initial_error: the fsmonitor--daemon stop cleanup step runs after .git has already been removed, so it always fails with "not a git repository". That looks like a second ordering bug in the same teardown path.

Affected version

GitHub Copilot CLI 1.0.80 (desktop app github.exe 1.1.12)

Steps to reproduce the behavior
  1. Open a worktree-backed session for a repository (this reproduced with an issue session).
  2. Let the session run normally — the agent's CWD is the worktree root.
  3. Without closing the session, choose Archive (or Delete) on that session.
  4. The app empties the worktree, removes .git, deregisters the worktree, then fails on rmdir.
  5. Observe Failed to archive session: ... (os error 32).
  6. Retrying reproduces it every time.
Expected behavior

Archiving a session should succeed on the first attempt, whether or not the session is currently running.

The teardown should stop the session's process tree (agency.exe and its copilot.exe / MCP children) — or move their working directory off the worktree — before removing the directory. Any fsmonitor--daemon stop call should also happen while .git still exists.

Additional context

Environment

  • OS: Windows 11 Enterprise Insider Preview, 10.0.26310.0
  • Arch: AMD64
  • App: GitHub Copilot 1.1.12 · CLI 1.0.80

Evidence that the live session is the blocker

Reading each process's real working directory out of its PEB at the moment of failure showed 8 processes rooted in the worktree — all belonging to the still-running session, all with live parents:

Process Parent
agency.exe github.exe (alive)
copilot.exe agency.exe (alive)
copilot.exe × 4 copilot.exe (alive)
computer-use-mcp.exe copilot.exe (alive)
pwsh.exe (tool shell) copilot.exe (alive)

Meanwhile the worktree was already empty, had no .git, and was absent from git worktree list — i.e. teardown had finished and only the CWD handles remained.

Minimal confirmation of the OS behavior

A two-arm test on a decoy empty directory, where only the CWD handle differed:

Arm Condition Result
A directory is a live process's CWD fails with the identical "used by another process" error
B same call, holder exited succeeds

Directory.Move fails the same way, so renaming-then-deleting is not a viable workaround either.

Secondary bug: each failed attempt leaks an orphan

Some archive attempts terminate the session's agency.exe but leave its copilot.exe child running. That orphan keeps its CWD on the worktree forever, so it becomes a permanent blocker that outlives the session. After three failed attempts this machine had three orphaned copilot.exe processes (started 15:11, 15:41, 15:55), each with a dead parent, all holding the same folder. This makes the failure progressively worse rather than idempotent, and leaves stray processes behind even after the user gives up.

Suggested fix

  1. Stop the session process tree (or SetCurrentDirectory it away from the worktree) before rmdir.
  2. Reap child processes when terminating agency.exe, so no orphan can outlive it.
  3. Run fsmonitor--daemon stop before removing .git.
  4. Consider surfacing which process holds the path when removal fails, instead of a bare os error 32.

Workaround

Terminate the session's process tree manually, then remove the (already empty) folder and run git worktree prune in the parent repo.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

github_app::workspace::handlers::lifecycle のアーカイブ/削除の teardown と、github_app::git::worktree の削除ロジックから始めます。セッションの実行中に Windows で再現し、その後、プロセスツリーのクリーンアップ、fsmonitor の停止、.git の削除、ディレクトリの削除がどの順序で行われるかを追跡します。孤立したプロセスやロックされた worktree がなく、アーカイブが成功すれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
git, shell
領域
backend, cli
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。