Restoring an archived worktree session fails because archive left the worktree folder on disk (Windows) · Issue #4933 · github/app · GitHub
Skip to content

Restoring an archived worktree session fails because archive left the worktree folder on disk (Windows) #4933

Open

Description

@iesmat

Short summary

Restoring an archived worktree session fails because archive left the worktree folder on disk after removing its Git registration. The folder could not be deleted because the session's Copilot CLI process was still holding it.

Affected version or release

  • GitHub Copilot app: 1.1.30
  • App-pinned Copilot CLI: 1.0.99-2
  • Agency: 2026.10.18.1
  • OS: Windows 11 Enterprise, build 26300, x64

Installation context

Windows desktop installation. A local repository project with multiple concurrent worktree-backed sessions.

What happened?

Restore failed with:

Restore failed
Failed to restore session: git ["worktree", "add"] failed: Preparing worktree (checking out '<branch>')
fatal: '<copilot-worktrees>/<repo>/<worktree-name>' already exists

Investigation

Observations just after the archive:

Time (local) Observation
10:11:43 The session's agency.exe started its copilot.exe child with --server --stdio --add-dir <worktree path>.
10:50:28 Session archived. A .copilot-pending-worktree-cleanup-<guid> marker file appeared in the worktree root.
~10:53 copilot.exe was still running, and its command line still contained the worktree path.
~10:53 Renaming the folder failed with The process cannot access the file because it is being used by another process.
~10:53 git worktree list no longer listed the path, and .git/worktrees/<name> was gone. Git's worktree metadata had been removed, but the folder had not.
~10:56 The session's agency.exe and copilot.exe had exited on their own, about 3 to 6 minutes after archive. Nothing was stopped manually.
~10:56 The folder could then be renamed.

Folder contents compared with the branch tip: no modified, deleted, untracked, or ignored files except the cleanup marker. The folder was a clean leftover with no user data.

The evidence suggests this sequence:

  1. Archive removes Git's worktree registration before the session's CLI process tree has exited.
  2. Deleting the folder then fails because the still-running CLI holds a handle in it. The app writes a pending-cleanup marker, presumably for a deferred retry.
  3. Restore runs git worktree add against the same path without checking for the pending-cleanup marker, the orphaned folder, or a still-running process. Restore fails.

The deferred cleanup may eventually remove the folder. Until it does, or if it never runs, Restore stays blocked.

Archive and Restore are not symmetric. Archive tries to remove the worktree, and Restore re-creates it from the branch. When removal only partly succeeds, the two operations disagree about whether the folder should exist.

Secondary issue: the first session start after Restore fails

After the leftover folder was moved aside:

  1. Restore succeeded and re-created the worktree.
  2. The app then reported that the session could not be started because its process was not there. This is paraphrased; the exact text was not captured.
  3. Clicking Try again started the session, and it has run normally since.

Restore may try to attach to or reuse the old session process, which had already exited, instead of starting a new one. It may also start the CLI before the re-created worktree is ready.

Steps to reproduce

  1. On Windows, create a worktree-backed session and let its CLI process start.
  2. Archive the session.
  3. Before the session's copilot.exe exits, restore the archived session, or restore it later if the deferred cleanup never ran.
  4. Observe the already exists error.
  5. Move the leftover folder aside and restore again. Restore succeeds, but the first session start fails until you click Try again.

Expected behavior

Archive and Restore should be consistent. Pick one model:

  • Option A: Archive fully removes the worktree. Stop the session's whole CLI process tree, including the agency.exe wrapper, and wait for it to exit. Then delete the folder, and only then unregister the worktree from Git. If the folder cannot be deleted, roll back the unregistration or retry later instead of leaving a half-removed state.
  • Option B: Archive keeps the worktree. Stop the CLI process but leave the worktree folder and its Git registration in place. Restore reattaches to the existing worktree. Remove the worktree only when the archived session is permanently deleted. This also keeps any uncommitted or ignored files across archive and Restore.

Separately:

  • Restore hardening: If the target path exists but is not a registered worktree, especially if it has a .copilot-pending-worktree-cleanup-* marker, finish the pending cleanup first. If the folder is locked or contains unexpected changes, move it aside, for example to <name>.orphaned-<timestamp>.
  • Restore start-up: Always start a new CLI process after Restore instead of expecting the archived session's process to still exist. Start it only after the worktree is ready.
  • Error message: Explain that a leftover folder from the previous archive is blocking Restore and give the path, instead of returning raw Git output.

Additional context

Workaround:

  1. Confirm that no copilot.exe or agency.exe process still references the worktree path.
  2. Move or delete <copilot-worktrees>/<repo>/<worktree-name>.
  3. Retry Restore.
  4. If the session fails to start, click Try again.

Related:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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