Windows Copilot CLI shim crashes when Get-Command copilot returns null
Bug
The Windows Copilot CLI shim can crash in Find-RealCopilot when Get-Command copilot returns no command.
Source file:
src/extension/chatSessions/vscode-node/copilotCLIShim.ps1
Current code:
$CopilotPath = (Get-Command copilot -ErrorAction SilentlyContinue).Source
# ...later:
if ($CurrentScript -eq $CopilotPath -or (Split-Path $CurrentScript -Parent) -eq (Split-Path $CopilotPath -Parent) -or ($CurrentScriptResolved -and $CopilotPathResolved -and $CurrentScriptResolved -eq $CopilotPathResolved)) {When Get-Command copilot -ErrorAction SilentlyContinue finds nothing, $CopilotPath is $null. The second -or clause still evaluates when the first clause is false, so PowerShell runs:
Split-Path $CopilotPath -ParentThat throws because Split-Path cannot bind a null/empty path.
Why this matters
This is the exact case the shim appears intended to handle: bootstrap or install when no real copilot command is available, while avoiding recursion if the shim shadows the real binary. Instead, the lookup path can fail before the install/update prompt path runs cleanly.
I reproduced this from the generated shim written by VS Code Insiders Copilot Chat:
%APPDATA%\Code - Insiders\User\globalStorage\github.copilot-chat\copilotCli\copilot.ps1Installed extension metadata on the affected machine:
name: copilot-chat
displayName: GitHub Copilot Chat
version: 0.48.2026050805
build: 1The bundled source in the installed VS Code Insiders app contains the same unguarded Split-Path $CopilotPath -Parent expression.
Expected behavior
If Get-Command copilot finds no real CLI, the shim should not crash. It should continue to the existing missing/install flow or return $null from Find-RealCopilot.
Suggested fix
Guard the directory comparison before calling Split-Path on $CopilotPath, for example:
$CurrentScriptDir = if ($CurrentScript) { Split-Path $CurrentScript -Parent } else { $null }
$CopilotPathDir = if ($CopilotPath) { Split-Path $CopilotPath -Parent } else { $null }
if (-not $CopilotPath -or $CurrentScript -eq $CopilotPath -or ($CurrentScriptDir -and $CopilotPathDir -and $CurrentScriptDir -eq $CopilotPathDir) -or ($CurrentScriptResolved -and $CopilotPathResolved -and $CurrentScriptResolved -eq $CopilotPathResolved)) {A smaller guard around only the existing second clause would also work:
($CopilotPath -and (Split-Path $CurrentScript -Parent) -eq (Split-Path $CopilotPath -Parent))Notes
This does not appear to be a user-authored script. The generated file is under globalStorage\github.copilot-chat\copilotCli, and the same shim text is embedded in the shipped Copilot Chat extension bundle.
Source: microsoft/vscode-copilot-chat