Worktree session checkout times out on Windows+WSL for submodule-containing repo, permanently blocking the session
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 2.1k
- Forks
- 157
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Creating a new project session with workspace type = Worktree repeatedly fails to complete checkout for a repo whose canonical checkout lives inside WSL (Ubuntu), accessed by the Windows-side app via \\wsl.localhost\... UNC paths. Once it fails, the session is permanently blocked: a preToolUse hook rejects every tool call (even read-only ones like git status) with:
Denied by preToolUse hook: The workspace checkout did not complete successfully. Do not retry this tool; tell the user the workspace needs to be retried or recreated.
There is no way to recover the session from within itself — it has to be abandoned/recreated, and it keeps failing the same way for the same repo.
Environment
- Windows host, repo checked out under WSL (Ubuntu) at
/home/<user>/source/workspaces/<repo>, accessed from the Windows-side app via\\wsl.localhost\Ubuntu\.... - Affected repo: working tree ~1.3 GB,
.git~143 MB, plus one git submodule (~55 MB.git, 1325 files). - New worktree sessions are provisioned under
copilot-worktrees/<repo>/<random-name>/.
What we found investigating from a working sibling session
Repeatedly, a freshly created worktree for a failed session was left in a partially checked-out state: only the top-level ~20 files/dirs were present (e.g. README.md, LICENSE, .github/, etc.), while the repo's git submodule was never cloned/initialized, and git status in that half-checked-out worktree showed the rest of the tree staged as deleted (index populated, working tree not fully materialized). This happened at least twice with different randomly-named worktrees, each time stopping at the same point (right before/at the submodule step).
We also found a stale .git/index.lock in the main repo checkout on one occasion (no process was actually holding it), which we removed — but the failure recurred on a subsequent attempt without any lock present, so the lock was a symptom/side effect, not the root cause.
Root cause (measured)
The Windows↔WSL UNC filesystem bridge is very slow for many-small-file operations:
git worktree addfor the full repo (1624 files), run natively inside WSL: ~26s- Submodule clone+checkout (1325 files), natively inside WSL: ~40s (total ~66s)
- A plain recursive file copy of that same 1325-file submodule folder, done from the Windows side over
\\wsl.localhost\...: 154.8 seconds — roughly 4x slower than the equivalent native-WSL git operation for a similar file count.
This suggests the app's worktree provisioning does some or all of its checkout/file materialization from the Windows side across the UNC bridge (rather than invoking git natively inside the WSL environment where the repo actually lives), and is timing out before the checkout — including the submodule — can finish. Given total time can approach/exceed a minute even natively, and 4x+ that over the bridge, it's easy to blow past whatever timeout budget session setup allows, especially for repos with submodules.
Impact
- New worktree sessions for such repos fail intermittently/repeatedly on Windows+WSL setups.
- Failed sessions are unrecoverable and provide no diagnostics — they just block every tool call.
- Leftover partial worktree directories and (occasionally) stale
index.lockfiles accumulate in the repo, requiring manual cleanup from a different, working session.
Suggested fixes
- When provisioning a worktree session for a repo whose canonical checkout lives inside WSL, perform the checkout (including submodule init) natively inside WSL (e.g. via
wsl.exe -e git ...) rather than through the Windows\\wsl.localhost\...UNC path. - Increase the checkout timeout for repos with submodules, or make it configurable.
- On checkout timeout/failure, clean up the partial worktree (and any stale
.git/worktrees/<name>metadata /index.lock) automatically instead of leaving it for manual remediation, and allow the session to at least report a clearer diagnostic/retry path. - Consider surfacing a more actionable error message pointing at the likely cause (e.g. "checkout timed out — repo may include large submodules and is on a slow filesystem bridge") instead of a generic "workspace checkout did not complete."
Repro steps
- On a Windows host, have a repo (with at least one git submodule) checked out inside a WSL distro, opened as a project via the
\\wsl.localhost\...path. - Create a new project session with workspace type "Worktree".
- Submit any prompt.
- Observe the session repeatedly fails all tool calls with the
preToolUsehook message above; inspecting the worktree directory from a separate working session shows an incomplete checkout stopped around the submodule step.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at worktree session provisioning and the preToolUse hook, then reproduce the checkout against a WSL path with a submodule while comparing native WSL git worktree add with Windows-side access. Done means the checkout completes reliably or reports a clear failure, and timed-out attempts do not leave a blocked session or partial worktree requiring manual cleanup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, ubuntu
- Domain
- developer-experience, operating-systems, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100