Agent host: clearer worktree git timeout errors and 60s budget#318242
Merged
roblourens merged 2 commits intoMay 26, 2026
Conversation
The 30s timeout in addWorktree/addExistingWorktree/removeWorktree was fine under normal conditions but bumped to 60s to absorb transient disk-I/O contention on the remote (e.g. many concurrent npm installs across multiple agent sessions). When git timed out, _runGit re-threw `new Error(stderr || error.message)`, which lost the timeout indicator. For `git worktree add`, stderr only contains git's progress meter (`Updating files: 0% (149/14834)`), so the surfaced error looked like git progress instead of a timeout. Now _runGit uses its own timer to flag the timeout case definitively and a new formatGitError helper produces messages like: git worktree timed out after 60000ms: <stderr tail> git worktree exited with code 128: fatal: invalid reference: ... The underlying ExecFileException is preserved as Error.cause. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves agent-host git worktree operations by increasing the timeout budget and making git timeout failures diagnosable (rather than surfacing git progress output as the error), with unit tests covering the new error formatting helper.
Changes:
- Increased
git worktreeoperation timeouts from 30s to 60s. - Reworked
_runGitto use a custom timeout timer so timeouts can be reliably distinguished from other kill paths. - Added
formatGitErrorhelper (exported for tests) plus unit tests covering timeout/signal/exit-code/fallback formatting.
Show a summary per file
| File | Description |
|---|---|
| src/vs/platform/agentHost/node/agentHostGitService.ts | Increases worktree timeouts; adds custom timeout handling; introduces formatGitError and uses Error.cause to preserve the original ExecFileException. |
| src/vs/platform/agentHost/test/node/agentHostGitService.test.ts | Adds unit tests for formatGitError classification branches. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Use child.on('exit') to clear the timeout, so 'timer' is no longer
referenced in the execFile callback before its declaration.
- Add summarizeStderrForError() to squash carriage-return-heavy progress
meter output into a single short line for the thrown error message,
with a 200-char cap.
- Log the full unmodified stderr at warn level via ILogService whenever
git exits with an error, so the raw output is still available even
though the thrown error message is summarized.
- Add unit tests for summarizeStderrForError and update the existing
formatGitError timeout test to exercise multi-line input.
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DonJayamanne
approved these changes
May 26, 2026
anthonykim1
added a commit
that referenced
this pull request
May 26, 2026
Squashed cherry-pick of 10 commits from main that are included in the Insiders build (183159e) people are verifying: - agentHost: show fetched URL for web_fetch (#318240) - Fix SSH remote agent host passphrase auth (#318244) - agentHost: add setting to disable worktreeCreated task auto-dispatch (#318243) - Agent host: clearer worktree git timeout errors and 60s budget (#318242) - Normalize LF to CRLF in agent host terminal tool output (#318257) - sessions: restore X-button removal of SSH remote agent host entries (#318262) - chat: fix duplicate command registration for agent-host-copilotcli (#318273) - launch: build copilot in compile; wait for CDP in launch.sh (#318272) - Preserve unread state across remote host disconnect (#318267) - Add more codenotify for terminal (#318285)
dileepyavan
pushed a commit
that referenced
this pull request
May 27, 2026
Squashed cherry-pick of 10 commits from main that are included in the Insiders build (183159e) people are verifying: - agentHost: show fetched URL for web_fetch (#318240) - Fix SSH remote agent host passphrase auth (#318244) - agentHost: add setting to disable worktreeCreated task auto-dispatch (#318243) - Agent host: clearer worktree git timeout errors and 60s budget (#318242) - Normalize LF to CRLF in agent host terminal tool output (#318257) - sessions: restore X-button removal of SSH remote agent host entries (#318262) - chat: fix duplicate command registration for agent-host-copilotcli (#318273) - launch: build copilot in compile; wait for CDP in launch.sh (#318272) - Preserve unread state across remote host disconnect (#318267) - Add more codenotify for terminal (#318285)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A user reported
createSessionfailing on an SSH remote with this misleading error in the side-effects log:The remote (a Mac Air) happened to be under heavy disk-I/O contention from many concurrent
npm installruns in other worktrees, sogit worktree addonly managed 149 of 14,834 files in 30s and got killed by the timeout inAgentHostGitService.addWorktree.Two underlying bugs surfaced:
_runGit, the timeout path didreject(new Error(stderr || error.message)). When git was killed before producing any diagnostic stderr, the surfaced error was just the progress meter, withcode=undefinedand no hint of what really happened.Changes
All three worktree operations (
addWorktree,addExistingWorktree,removeWorktree --force) now use a 60s timeout instead of 30s. All three can do real filesystem work proportional to the worktree's content, so they share the same bumping consistently rather than leavingremoveWorktreeat 30s.rationale_runGit: replacedexecFile's built-intimeoutoption with our ownsetTimeoutthat flips adidTimeOutflag before callingchild.kill(). The flag lets us definitively distinguish a timeout from other kill paths (rather than "killed && signal, likely a timeout"). The timer is cleared viachild.on('exit').New exported helper
formatGitError: classifies the failure (timeout / signal / exit code / other) and produces messages like:git worktree timed out after 60000ms: Updating files: 0% (149/14834)git worktree exited with code 128: fatal: invalid reference: missing-branchspawn git ENOENTThe underlying
ExecFileExceptionis preserved asError.causeso downstream consumers can still inspect it.summarizeStderrForErrorhelper: git progress output is full of\r-separated repaints (e.g.Updating files: 0% (7/14834)\rUpdating files: 0% (149/14834)\r). Stripping naively still left a noisy multi-line blob in the error. The helper now keeps only the last non-empty line and caps at 200 chars, so the error message is a clean one-liner.Full stderr is still logged. Since the thrown error message is summarized,
_runGitnow logs the complete unmodified stderr atwarnlevel viaILogServiceon any git failure, so no diagnostic context is lost.Unit tests for
formatGitError(four classification branches) andsummarizeStderrForError(empty / whitespace / multi-line progress / normal one-liner / truncation).After this change, the same failure would be surfaced as a one-liner that immediately says "timed out after diagnosable from the side-effects log without log archaeology, with the full raw stderr available in the agent-host log if deeper inspection is needed.60000ms"
(Written by Copilot)