Fix Windows .bat/.cmd shim spawn failure in copilotSdk.ts by adding early-exit to external server mode#53
Merged
digitarald merged 4 commits intomicrosoft:mainfrom Mar 15, 2026
Conversation
…ver mode Co-authored-by: nicolehaugen <10600161+nicolehaugen@users.noreply.github.com>
…im, revert test scope Co-authored-by: nicolehaugen <10600161+nicolehaugen@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Improves Windows compatibility for Copilot SDK startup by avoiding SDK-managed spawning when the discovered Copilot CLI path is a Windows .bat/.cmd shim (which can fail with spawn EINVAL), and instead going directly to the existing external server mode.
Changes:
- Add
.bat/.cmdshim detection (Windows-only) to skip the SDK-managed startup path and immediately use external server mode. - Treat
spawn EINVALas a recognized trigger for falling back to external server mode (as a safety net).
github-actions bot
pushed a commit
that referenced
this pull request
Mar 15, 2026
- Add [Unreleased] section documenting features from PRs #55, #60, #53, #52: - instructions --dry-run flag - VS Code batch instructions and multi-root workspace support - Enhanced .NET/F# detection with framework parsing - Windows .bat/.cmd spawn EINVAL fix - ESM/CJS createRequire banner fix - Model default updated to claude-sonnet-4.6 - TUI key binding changes (R for readiness, N for nested area) - Terminology de-branding - Fix stale claude-sonnet-4.5 reference in [2.0.0] section Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Summary
##Repro:
1.) Run: agentrc instructions on Windows machine when underlying call to copilot sdk is resolved from VS Code global Storage as copilot.bat
2.) Error:
Generating instructions...
[agentrc:copilot] trying override AGENTRC_COPILOT_CLI_PATH=C:\Users\nicolela\AppData\Roaming\Code\User\globalStorage\github.copilot-chat\copilotCli\copilot.bat
[agentrc:copilot] override CLI is compatible
[agentrc:copilot] validating CLI compatibility with C:\Users\nicolela\AppData\Roaming\Code\User\globalStorage\github.copilot-chat\copilotCli\copilot.bat
[agentrc:copilot] creating SDK client with cliPath=C:\Users\nicolela\AppData\Roaming\Code\User\globalStorage\github.copilot-chat\copilotCli\copilot.bat useStdio=false
Error: Failed to generate instructions with Copilot SDK. Ensure the Copilot CLI is installed (copilot --version) and logged in. spawn EINVAL
Problem
On Windows, when
@github/copilotis not installed globally via npm, the Copilot CLI discovery chain infindCopilotCliConfig()(incopilot.ts) resolves to a.batshim at:This is step 3 of the 6-step discovery chain:
AGENTRC_COPILOT_CLI_PATHenv var overridenode.exe+npm-loader.js) — no.batissuecopilot.baton Windows ← this is where the problem occurswhere copilot(PATH lookup)When a user has Copilot only through the VS Code extension (not npm-installed), discovery lands on step 3 and returns
{ cliPath: "...\\copilot.bat" }.Node.js
child_process.spawn()calls the WindowsCreateProcessAPI, which can only execute PE binaries (.exe,.dll). A.batfile is a script that needscmd.exeas its interpreter. Spawning it directly produces:The SDK-managed primary attempt always fails on this path. Before this fix, it would:
spawn EINVALorCopilot CLI not found at cmd.batincmd /c)This wasteful "sacrificial" primary attempt adds latency on every invocation.
How this situation occurs
A developer installs VS Code with the GitHub Copilot Chat extension. The extension downloads the Copilot CLI to its globalStorage as
copilot.bat. If the developer also runsnpm install -g @github/copilot, discovery resolves at step 2 tonode.exe+npm-loader.js(a real PE binary), and there's no issue. But if they only have the VS Code extension, step 2 fails and step 3 returns the.batshim.Solution
Two changes in
packages/core/src/services/copilotSdk.ts:.bat/.cmdshims (alongside existing npx early-exit) - IncreateCopilotClient(), detect.bat/.cmdpaths on Windows and skip the SDK-managed primary attempt entirely — go straight to external server mode, just like the existingisNpxcheck.shouldFallbackToExternalServer()- Add"spawn einval"as a recognized fallback trigger so that if the early-exit is somehow bypassed (e.g. a future code path), the error is still caught.Checklist