-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Bug: CLI produces no stdout in child process (Start-Process) on Windows — blocks headless automation #2525
Description
Bug: Copilot CLI v1.0.18 produces no stdout/stderr when launched via Start-Process on Windows
Summary
When launching copilot as a child process via PowerShell's Start-Process on Windows, the CLI produces zero bytes of output to both stdout and stderr, even though it runs successfully in an interactive shell. This is a regression — the same Start-Process approach captured output correctly on March 31, 2026 but stopped working by April 5, 2026 (likely after a CLI update).
Environment
- Copilot CLI version: 1.0.18
- OS: Windows 11 (10.0.26200)
- PowerShell: 7.x (pwsh)
- Node.js: v22.21.0
- Install method: WinGet + npm global
Reproduction Steps
Works (interactive shell, output captured):
cd C:\path\to\git-repo
$output = & copilot -p "Say hello" --yolo --no-ask-user -s --no-color --disable-builtin-mcps 2>&1
# $output contains the response ✅Fails (child process via Start-Process, 0 bytes):
# Method 1: Start-Process with redirect (0 bytes)
Start-Process -FilePath copilot.cmd -ArgumentList '-p "Say hello" --yolo --no-ask-user -s --no-color --disable-builtin-mcps' -NoNewWindow -RedirectStandardOutput out.txt -RedirectStandardError err.txt -Wait
# out.txt = 0 bytes, err.txt = 0 bytes
# Method 2: Launcher script with > redirect (0 bytes)
# launcher.ps1 contains: & copilot.cmd -p "Say hello" --yolo -s --no-color --disable-builtin-mcps > out.txt 2> err.txt
Start-Process -FilePath pwsh -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File launcher.ps1" -NoNewWindow -Wait
# out.txt = 0 bytes
# Method 3: Launcher script with pipeline Out-File (0 bytes in child process)
# launcher.ps1 contains: & copilot.cmd -p "Say hello" --yolo -s --no-color --disable-builtin-mcps 2>&1 | Out-File out.txt
Start-Process -FilePath pwsh -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File launcher.ps1" -NoNewWindow -Wait
# out.txt = 0 bytes (but works when run directly in current shell!)
# Method 4: Start-Transcript (captures PS header only, not copilot output)
# launcher.ps1 contains: Start-Transcript out.txt; & copilot.cmd ...; Stop-Transcript
# out.txt = PS version header only, no copilot outputExpected Behavior
All four methods should capture copilot's response text. Method 1 (Start-Process -RedirectStandardOutput) worked correctly on March 31 with the same codebase.
Actual Behavior
Copilot CLI appears to write output to the Windows console handle directly rather than stdout. This means:
- Interactive shell:
& copilot ... 2>&1captures output via PowerShell's pipeline (which intercepts console writes in the current session) - Child process: The child
pwshprocess gets a different console session, and copilot's console writes go to a handle that no redirection mechanism can capture
Evidence of Regression
Dispatch logs from March 31 using the same Start-Process -RedirectStandardOutput approach show captured output (924–2311 bytes). Dispatch logs from April 5 show 0 bytes across all attempts. The only change between sessions was a copilot CLI update.
Impact
This blocks all headless/automated use of Copilot CLI on Windows, including:
- Dispatching work to child squad repos via
Start-Process - Running Copilot CLI in CI/CD pipelines
- Any automation that launches copilot as a background process and captures results
Workaround
The only working approach is invoking copilot in the current interactive shell session using & copilot ... 2>&1. This doesn't work for background/async automation because it blocks the parent session.
Suggested Fix
Copilot CLI should write to stdout (file descriptor 1) rather than directly to the Windows console handle (WriteConsoleW / WriteFile to CONOUT$). This would make all standard redirection mechanisms work (>, Start-Process -RedirectStandardOutput, pipes, Start-Transcript).
Alternatively, provide a --output-file <path> flag that writes the session transcript to a file, bypassing the console entirely.