[Windows] Bash tool: MSYS2 builtins and POSIX-compiled binaries cannot write to stdout; native Windows exes work fine
Environment
- OS: Windows 11 Enterprise 10.0.26100
- Claude Code: 2.1.45
- Shell: Git for Windows
CLAUDE_CODE_GIT_BASH_PATH:C:\Users\iwheeler\AppData\Local\Programs\Git\bin\bash.exe
Summary
On Windows, the Bash tool fails silently for all bash builtins and MSYS2-compiled binaries. Native Windows executables (git.exe, python.exe, where.exe) work correctly. This makes the Bash tool almost entirely unusable on Windows.
Reproduction
These fail with no output:
echo hello # exit 1, no output
ls -la # exit 2, no output
pwd # exit 1, no output
/usr/bin/printf "test" # exit 1, no output
These work:
git --version # exit 0, correct output
python -c "print('hello')" # exit 0, correct output
where python # exit 0, correct output
Root Cause (diagnosed)
Node.js creates Windows anonymous pipes for subprocess I/O. MSYS2's POSIX emulation layer has its own pipe-type detection: it checks whether stdout is an MSYS2 pipe, a Windows console, or a generic Windows pipe. When the pipe is a Node.js anonymous pipe, MSYS2's CRT write() call fails with EPIPE — so bash builtins and MSYS2-compiled binaries exit 1 with no output.
Native Windows executables bypass this entirely — they call WriteFile()/WriteConsole() directly against the Windows HANDLE, which works fine regardless of pipe type.
Secondary issue: MSYS2 path conversion mangles flags passed to native Windows programs. Running cmd /c "echo hello" launches cmd.exe interactively instead of executing the command, because MSYS2 converts /c to C:\ before handing off to cmd.exe. This is controlled by MSYS_NO_PATHCONV.
This is a known Node.js + MSYS2/Cygwin interop issue.
Suggested Fix
One or more of:
- Spawn bash via
winptyto provide a PTY that MSYS2 can properly write to - Set MSYS2 environment variables in the subprocess environment:
MSYS_NO_PATHCONV=1MSYS2_ARG_CONV_EXCL=*MSYS2_TTY_HACK=1
- Use a native PTY allocator (e.g.
node-pty) rather than anonymous pipes
Workaround
Use native Windows executables directly. python -c "..." works; echo, ls, pwd do not.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗