Does this issue occur when all extensions are disabled?: No
- VS Code Version: 1.122.1 (8761a55, arm64)
- OS Version: macOS 26.4 (Apple Silicon)
- Built-in GitHub Copilot Chat: 0.50.1 / bundled @github/copilot SDK 1.0.49
- Also involved: Dart-Code + Flutter iOS build (SwiftPM), Xcode 26.5
Summary
The @github/copilot SDK bundled inside the built-in Copilot Chat extension mutates the shared extension host's process.env to inject git hardening config (safe.bareRepository=explicit). Every child process spawned by any other extension afterwards inherits it, breaking any tool that operates on bare git repos. It broke all Flutter iOS device builds launched from VS Code with a misleading error, costing ~3 hours to diagnose:
Failed to build iOS app
Could not build the precompiled application for the device.
Uncategorized (Xcode): xcodebuild encountered an error (74)
Terminal flutter run and Xcode both work fine — only VS Code launches fail, because only the extension-host environment is poisoned.
Root cause (from the shipped bundle)
extensions/copilot/node_modules/@github/copilot/sdk/index.js, de-minified:
function bHt() {
let count = parseInt(process.env.GIT_CONFIG_COUNT || "0", 10);
// ... returns early if already present ...
process.env.GIT_CONFIG_COUNT = String(count + 1);
process.env[`GIT_CONFIG_KEY_${count}`] = "safe.bareRepository";
process.env[`GIT_CONFIG_VALUE_${count}`] = "explicit";
}
This writes to the global process.env of the shared extension host, not to the env of Copilot's own child processes.
Evidence of cross-extension contamination
The Flutter daemon spawned by the (unrelated) Dart extension inherits the injection:
$ ps eww <flutter-daemon-pid> | tr ' ' '\n' | grep GIT_
GIT_CONFIG_VALUE_0=explicit
GIT_CONFIG_KEY_0=safe.bareRepository
GIT_CONFIG_COUNT=1
The VS Code main process and the extension host show no such variables at spawn time — confirming the mutation happens at runtime, after Copilot activates. It's also racy: a Flutter daemon spawned before Copilot activates is clean, so the failure is intermittent across windows/sessions.
Why it breaks SwiftPM / Flutter iOS builds
SwiftPM stores repository caches as bare repos (~/Library/Caches/org.swift.swiftpm/repositories/). With safe.bareRepository=explicit injected via env, every git call xcodebuild/SwiftPM makes against those caches dies:
fatal: cannot use bare repository '.../org.swift.swiftpm/repositories/firebase-ios-sdk-...' (safe.bareRepository is 'explicit')
xcodebuild: error: Could not resolve package dependencies
→ "xcodebuild encountered an error (74)"
A user-level git config --global safe.bareRepository all cannot fix this — env-injected config outranks global config. Users have no clean way to defend themselves.
Steps to Reproduce
- Open a Flutter project with SwiftPM-based iOS deps (e.g. Firebase) in VS Code with the built-in Copilot Chat active.
- Hit Run / F5 targeting a physical iOS device (or run the minimal repro below).
- Build fails with
xcodebuild encountered an error (74). Terminal flutter run and Xcode succeed.
Minimal repro of the poisoned git call (no Flutter needed):
cd ~/Library/Caches/org.swift.swiftpm/repositories/<any>/
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=safe.bareRepository GIT_CONFIG_VALUE_0=explicit git fetch
# → fatal: cannot use bare repository ...
git fetch
# → works fine
Expected behavior
Copilot's git hardening should be scoped to the env passed to its own child processes (spawn(cmd, { env: { ...process.env, GIT_CONFIG_* } })), never written into the shared extension host's global process.env. The host is shared by all extensions; mutating its env contaminates unrelated products.
Workarounds (for others hitting this)
- Dart/Flutter: add
"dart.env": { "GIT_CONFIG_COUNT": "0" } to settings, then Reload Window; or
"chat.disableAIFeatures": true to disable the built-in Copilot entirely.
Does this issue occur when all extensions are disabled?: No
Summary
The
@github/copilotSDK bundled inside the built-in Copilot Chat extension mutates the shared extension host'sprocess.envto inject git hardening config (safe.bareRepository=explicit). Every child process spawned by any other extension afterwards inherits it, breaking any tool that operates on bare git repos. It broke all Flutter iOS device builds launched from VS Code with a misleading error, costing ~3 hours to diagnose:Terminal
flutter runand Xcode both work fine — only VS Code launches fail, because only the extension-host environment is poisoned.Root cause (from the shipped bundle)
extensions/copilot/node_modules/@github/copilot/sdk/index.js, de-minified:This writes to the global
process.envof the shared extension host, not to the env of Copilot's own child processes.Evidence of cross-extension contamination
The Flutter daemon spawned by the (unrelated) Dart extension inherits the injection:
The VS Code main process and the extension host show no such variables at spawn time — confirming the mutation happens at runtime, after Copilot activates. It's also racy: a Flutter daemon spawned before Copilot activates is clean, so the failure is intermittent across windows/sessions.
Why it breaks SwiftPM / Flutter iOS builds
SwiftPM stores repository caches as bare repos (
~/Library/Caches/org.swift.swiftpm/repositories/). Withsafe.bareRepository=explicitinjected via env, every git call xcodebuild/SwiftPM makes against those caches dies:A user-level
git config --global safe.bareRepository allcannot fix this — env-injected config outranks global config. Users have no clean way to defend themselves.Steps to Reproduce
xcodebuild encountered an error (74). Terminalflutter runand Xcode succeed.Minimal repro of the poisoned git call (no Flutter needed):
Expected behavior
Copilot's git hardening should be scoped to the env passed to its own child processes (
spawn(cmd, { env: { ...process.env, GIT_CONFIG_* } })), never written into the shared extension host's globalprocess.env. The host is shared by all extensions; mutating its env contaminates unrelated products.Workarounds (for others hitting this)
"dart.env": { "GIT_CONFIG_COUNT": "0" }to settings, then Reload Window; or"chat.disableAIFeatures": trueto disable the built-in Copilot entirely.