microsoft / microsoft/vscode

agentHost: a transient git failure can permanently freeze a folder-isolated session's project

Open
#329,943 0 comments 0 reactions 1 assignee Claimed by @anthonykim1 View on GitHub
bug
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

Found while reviewing the two competing fixes for #329880 (#329925 and #329932). It is out of scope for both, but the same failure mode, so filing it separately rather than losing it when one of them merges.

## What happens

`resolveGitProject` (`src/vs/platform/agentHost/node/copilot/copilotGitProject.ts`) resolves a session's project and, when the primary worktree cannot be resolved, **falls back to the checkout root**. `CopilotAgent` then persists that fallback and marks it resolved (`node/copilot/copilotAgent.ts`, around the `projectResolved` write).

The fallback is indistinguishable from a real answer, because `getWorktreeRoots` swallows every git failure into `[]` — a repository that is genuinely not a worktree, a git that timed out, an index-lock contention, and an `EAGAIN` under load all look identical.

So a *momentary* condition — a network volume briefly unavailable, a slow FUSE mount, git timing out under load — can be persisted as a settled answer.

## Why it is durable

Unlike worktree-isolated sessions, **folder-isolated sessions have no worktree metadata migration to correct it later**. Nothing re-derives the value, so a transient blip becomes a permanently mis-grouped session in the Agents window, with no user affordance to repair it short of editing the session database.

## Reproduction

A fake git service that fails once and then recovers returns the linked checkout root **both** times, with only one git call — the persisted fallback is never revisited.

## Suggested direction

Return a typed `{ root, confirmed }` from the resolution rather than a bare `URI`, and never persist an unconfirmed fallback as resolved. An unconfirmed project should stay unpersisted so a later attempt can settle it.

This is the same shape as two bugs already fixed in #329932: an unconfirmed value must never be certified, and "git failed" must not be collapsed into "git answered no". Worth applying the same rule here.

## Notes

- Affects both #329925 and #329932 equally; neither introduces it and neither fixes it.
- Related hardening already landed in #329932: `canonicalizeExistingPath` now reports absence only for `ENOENT`/`ENOTDIR` so that an unreadable or briefly-unavailable path is not mistaken for a deleted one.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.