Copilot CLI on Windows is hardcoded to use PowerShell 6+, not bash or zsh. This architectural constraint means running it from Cygwin creates an inherent incompatibility layer where every command gets translated through PowerShell, causing the path corruption and file truncation you're experiencing. The /cygdrive/g becoming G:\cygdrive\g issue is a direct consequence of Windows' path interpretation rules encountering Cygwin's virtual filesystem paths that only PowerShell receives—but doesn't understand. The solution isn't better configuration; it's using a supported environment like WSL.
The new GitHub Copilot CLI (the standalone copilot command, not the deprecated gh copilot extension) executes all shell commands through a hardcoded PowerShell 6+ dependency on Windows. Issue #508 on the copilot-cli repository confirms: "It seems like it's a hardwired dependency... I tried for over 30 minutes to get it to use Bash for terminal commands to no avail."
When you run Copilot CLI from Cygwin's zsh, here's what actually happens:
- Copilot CLI detects it's on Windows and spawns
pwsh.exe - Your command containing
/cygdrive/g/pathgets passed to PowerShell - PowerShell—a native Windows application—receives a path starting with
/ - Windows interprets
/cygdrive/gas a root-relative path (Microsoft's Rule #3: "relative to root of current drive") - If your current drive is G:, Windows resolves this to
G:\cygdrive\g
This explains the bizarre path corruption. The /cygdrive prefix is a Cygwin-only virtual mount that has zero meaning to any Windows application, including PowerShell. The conversion must happen before the path leaves Cygwin.
The cygpath utility exists specifically for this conversion, but Copilot CLI doesn't use it because Copilot CLI doesn't know it's running in a Cygwin environment—it just sees Windows and calls PowerShell. The translation gap manifests as:
| What Cygwin sends | What PowerShell receives | What Windows resolves |
|---|---|---|
/cygdrive/g/file.txt |
/cygdrive/g/file.txt |
G:\cygdrive\g\file.txt |
/home/user/project |
/home/user/project |
G:\home\user\project (current drive root) |
/tmp/heredoc.tmp |
/tmp/heredoc.tmp |
G:\tmp\heredoc.tmp |
The heredoc and file write failures stem directly from this: when zsh creates a heredoc, it writes to /tmp. When that operation gets forwarded through Copilot CLI to PowerShell, PowerShell tries to write to a nonexistent G:\tmp directory—or worse, a completely different location.
Three system-level factors cause consistent truncation across all write methods:
Text mode conversion is the most likely culprit. Cygwin can operate in text mode (converting LF↔CRLF automatically) or binary mode. If your /cygdrive mount uses text mode, every newline written becomes two bytes. When files are subsequently read in binary mode—or by tools expecting specific byte positions—the count mismatches cause apparent truncation. Check your mount mode: mount | grep cygdrive. The fix is adding binary to /etc/fstab:
none /cygdrive cygdrive binary,noacl,posix=0,user 0 0
NTFS ACL conflicts create files that Cygwin can write but Windows applications can't fully access. Cygwin maps POSIX permissions to Windows ACLs, sometimes creating "NULL SID" deny entries that confuse Windows programs. The noacl mount option prevents this by ignoring filesystem ACLs entirely.
Buffering behavior differs between environments. Cygwin's BUFSIZ is only 1KB versus Linux's 8KB. When large content is piped through multiple processes—zsh to Copilot CLI to PowerShell—block buffering can cause premature flush or incomplete writes, especially when timeouts occur. Copilot CLI's default shell tool timeout is relatively short; long operations may not complete before Copilot considers them "done."
Cygwin's /dev/fd/N implementation behaves differently from Linux. The file descriptor backing a heredoc may be "gone" before the child process accesses it. When heredocs use file descriptors (like 3<<EOF), Cygwin's implementation of /proc/self/fd can fail with "No such file or directory." This is a fundamental implementation difference, not a configuration issue.
Additionally, heredoc temp files go to /tmp. If /tmp doesn't exist in the expected location—or if Cygwin's /tmp doesn't map to where PowerShell expects Windows temp files—the heredoc creation fails entirely. The error "cannot create temp file for here document" indicates this path mismatch.
The recommended solution is WSL, not Cygwin. Copilot CLI officially supports macOS, Linux, and Windows via WSL. In WSL2, you get a real Linux kernel with native bash/zsh support—no PowerShell translation layer, no path conversion issues, no heredoc compatibility problems. The commands Copilot suggests execute in actual Linux bash.
If you must continue using Cygwin:
- Use a wrapper script that converts all paths before they reach Copilot CLI:
#!/bin/bash
# Always use cygpath -m (mixed mode: C:/path/to/file)
export HOME=$(cygpath -m "$HOME")
export TMP=$(cygpath -m /tmp)
cd "$(cygpath -m "$(pwd)")"
copilot.exe "$@"-
Never pass Cygwin paths to Windows programs. Every time you reference a file to Copilot CLI, manually convert it:
$(cygpath -w /cygdrive/g/file.txt)producesG:\file.txt. -
Consider MSYS2 instead of Cygwin if you need Cygwin-like functionality. MSYS2 provides automatic path conversion when calling Windows executables—Unix paths auto-convert without manual
cygpathcalls. You can disable this selectively withMSYS2_ARG_CONV_EXCL. -
For file operations specifically, bypass Copilot's command execution entirely. Copy generated commands to clipboard, switch to a native terminal (PowerShell, cmd, or Windows Terminal), and execute there. This eliminates the double-translation problem.
Copilot CLI's configuration (~/.copilot/config.json) controls behavioral options like banner display and tool permissions—not shell interpreter selection. There is no setting to make Copilot CLI use bash instead of PowerShell on Windows. GitHub Issue #508 requesting Git Bash support remains open with no indication it's planned.
The older gh copilot extension (now deprecated as of October 2025) offered gh copilot alias -- zsh for shell integration, but this generated aliases for your shell to call Copilot—it didn't change how Copilot executed commands internally.
Your file truncation and path corruption issues aren't bugs in your zsh configuration or Ruby scripts—they're architectural consequences of running a PowerShell-dependent tool from a POSIX emulation layer. Every command passes through two incompatible path namespaces with no automatic translation.
For reliable Copilot CLI usage: migrate to WSL where Copilot CLI works natively. For continuing Cygwin usage: accept that file operations suggested by Copilot will require manual path conversion, or execute them in a native Windows shell. No amount of Cygwin configuration can make PowerShell understand /cygdrive paths—that translation must happen before commands leave the Cygwin environment.