You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
shell.resolveSpawnCommand walks PATH × PATHEXT with statSync on every spawn and picks Git's cmd launcher #11221
Every child process the server starts goes through resolveSpawnCommand, which re-scans PATH synchronously each time and, on Git for Windows, resolves git to the cmd\git.exe launcher. Each git command is therefore two processes, and the lookup itself burns event-loop time on every spawn.
Diagnosis
processRunner.ts:294 calls resolveSpawnCommand for every process. resolveSpawnExecutableWithNode (packages/shared/src/shell.ts:95-133) loops over every PATH entry times every candidate extension and calls NodeFS.statSync for each. Nothing is memoized, and the work is synchronous on the event loop.
On this machine that is ~22 ms per spawn. 2345 shell.resolveSpawnCommand spans in a 76-minute trace; ~580 s over 13 h.
Compare shell.resolveSpawnCommand span durations in server.trace.ndjson, and trace process creation: each runGitCommand shows git.exe (launcher) → git.exe (mingw64).
Expected: resolve a command once per (command, PATH, PATHEXT) and reuse it; resolve git to the real binary.
Actual: a full synchronous PATH scan per spawn, and a two-process git.
Version
0.0.41-nightly.20260908.1414 (desktop); code unchanged on main @ 211618f.
Environment
Windows 11 Pro 26200, git 2.55.0.windows.5, gh 2.100.0.
Evidence
shell.resolveSpawnCommand 2345 spans / 76 min (~22 ms each on this machine)
processRunner.runProcessCore 2345
Related issues
#2537 (per-process console cost), #7570 (stale shim resolution, closed). Neither covers the missing memoization or the launcher choice.
Fix applied or workaround
None. PATH order could be changed by hand, but the resolver would still scan on every spawn.
Filed by
Claude Code (Claude Fable 5.1), following the t3 triage playbook from a checkout of main.
What happened
Every child process the server starts goes through
resolveSpawnCommand, which re-scansPATHsynchronously each time and, on Git for Windows, resolvesgitto thecmd\git.exelauncher. Each git command is therefore two processes, and the lookup itself burns event-loop time on every spawn.Diagnosis
processRunner.ts:294callsresolveSpawnCommandfor every process.resolveSpawnExecutableWithNode(packages/shared/src/shell.ts:95-133) loops over everyPATHentry times every candidate extension and callsNodeFS.statSyncfor each. Nothing is memoized, and the work is synchronous on the event loop.shell.resolveSpawnCommandspans in a 76-minute trace; ~580 s over 13 h.Git\cmdonPATHahead ofGit\mingw64\bin, so the first hit iscmd\git.EXE, a launcher that execs the realmingw64\bin\git.exe. Every git command is two process creations (plus aconhost.exeeach, see [Bug]: Frequent cmd.exe / conhost flashes on Windows from provider probe & VCS process kill paths #2537).Steps to reproduce
t3 servewith a git project and let the background sweeps run (see Thread PR discovery and settlement sweeps run every minute without client demand, and their caches expire before the next sweep #11220).shell.resolveSpawnCommandspan durations inserver.trace.ndjson, and trace process creation: eachrunGitCommandshowsgit.exe(launcher) →git.exe(mingw64).Expected: resolve a command once per
(command, PATH, PATHEXT)and reuse it; resolvegitto the real binary.Actual: a full synchronous
PATHscan per spawn, and a two-process git.Version
0.0.41-nightly.20260908.1414 (desktop); code unchanged on
main@ 211618f.Environment
Windows 11 Pro 26200, git 2.55.0.windows.5, gh 2.100.0.
Evidence
Related issues
#2537 (per-process console cost), #7570 (stale shim resolution, closed). Neither covers the missing memoization or the launcher choice.
Fix applied or workaround
None.
PATHorder could be changed by hand, but the resolver would still scan on every spawn.Filed by
Claude Code (Claude Fable 5.1), following the
t3 triageplaybook from a checkout ofmain.