Bash tool fails with exit code 1 on Windows - stdout capture broken
Status Open
Reported on v2.1.45
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 7 comments · opened Feb 18, 2026
Description
All Bash tool commands that produce stdout output fail with exit code 1 on Windows. Commands that produce no output (like true) succeed. Writing to files works correctly.
Environment
- Claude Code version: 2.1.45
- OS: Windows 11 Pro for Workstations (10.0.26100)
- Shell: Git Bash (MINGW64), GNU bash 5.2.37(1)-release (x86_64-pc-msys)
- Platform: MINGW64_NT-10.0-26100, x86_64
Steps to Reproduce
- Launch Claude Code on Windows with Git Bash
- Ask Claude to run any command that produces stdout output
Observed Behavior
| Command | Result |
|---------|--------|
| true | exit 0 ✅ |
| echo "test" | exit 1 ❌ |
| pwd | exit 1 ❌ |
| ls | exit 1 ❌ |
| builtin echo "test" | exit 1 ❌ |
| echo "test" > /tmp/file.txt 2>&1; true | exit 0 ✅ (file contains "test") |
Terminal shows: /usr/bin/echo: /usr/bin/echo: cannot execute binary file
Diagnostics
/usr/bin/echo.exeis a valid Windows binary:PE32+ executable for MS Windows 5.02 (console), x86-64/usr/bin/ls.exeis also a valid PE32+ executable- Bash builtins work when output is redirected to a file
- The issue appears to be with stdout capture by Claude Code, not with the binaries themselves
MSYSTEM=MINGW64,TERM=xterm-256color
What I've Tried
- Setting
$env:SHELLto various Git Bash paths (C:\Program Files\Git\bin\bash.exe,C:\Program Files\Git\usr\bin\bash.exe) - Deleting
~/.claude/shell-snapshots/ - Reinstalling Git for Windows
- Updating Claude Code to latest version (2.1.45)
- Running from different terminals (PowerShell, CMD, Git Bash)
- Setting
$env:SHELL = "powershell"(Claude Code still uses bash)
Expected Behavior
Bash commands should execute and their stdout output should be captured and returned to the agent.
7 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Windows 11
Git bash
environment
----
I believe 2.1.45 is super buggy crap trash. I spend some time investigating however I endup rolling back to stable version.
I will never use
claude updateagain.Bash commands keep returning "Error: Exit code 1" after the standalone Claude installation.
`
● Bash(pwd 2>&1)
⎿ Error: Exit code 1
● Bash(/bin/pwd 2>&1; echo "EXIT: $?")
⎿ Error: Exit code 1
● Bash(echo "hello world")
⎿ Error: Exit code 1
● Bash(whoami)
⎿ Error: Exit code 1
● Bash(echo "hello") ⎿ Error: Exit code 1 `
Only this works:
● Bash(true)⎿ (No output)
I'm on windows, Claude Code version is 2.1.45.
Bash works fine outside of Claude Code.
Edit: Found the likely culprit in the 2.1.45 changelog:
Root Cause Analysis
I've been debugging this as a user on the same setup (Windows 11, Git Bash MINGW64, CC 2.1.45). Here's what the evidence points to:
The Pattern
The key observation from the issue is:
| Command | Produces stdout? | Result |
|---|---|---|
|
true| No | exit 0 ||
echo "test"| Yes | exit 1 ||
builtin echo "test"| Yes (builtin) | exit 1 ||
echo "test" > /tmp/file.txt 2>&1; true| No (redirected) | exit 0, file has content |Two Separate Failures
1. External MSYS2 binaries can't execute in the CC subprocess
The error
/usr/bin/echo: /usr/bin/echo: cannot execute binary fileshows that external commands in/usr/bin/(likels,pwd,echo) can't be loaded as executables within the CC-spawned subprocess. The shell itself runs fine, but child processes of that shell can't execute MSYS2 binaries. This likely points to an environment issue (missingMSYSTEM, wrongPATH, or a different subprocess creation method that doesn't properly inherit the MSYS2 runtime context).2. The stdout pipe itself is broken
Even
builtin echo(which doesn't spawn an external process) fails with exit 1. This means writing to file descriptor 1 (stdout) fails in the CC subprocess. The pipe that CC sets up to capture command output isn't compatible with MSYS2's POSIX emulation layer. Writing to files bypasses this completely, which is why the redirect workaround succeeds.Likely Root Cause
CC v2.1.45 likely changed how it creates the stdout pipe or spawns the child process on Windows. Candidates:
child_process.spawn), MSYS2's translation layer may not handle them correctly.stdioconfig change: A change from'inherit'to['pipe', 'pipe', 'pipe'](or similar) in the Node.jsspawn()options could break MSYS2 compatibility while working fine on native Windows shells.MSYSTEM=MINGW64or related MSYS2 env vars aren't passed to the subprocess, the MSYS2 runtime can't properly initialize, which would explain why binaries in/usr/bin/can't execute.Workaround
Until patched, redirecting all output to files works:
Then use the Read tool to read the file contents.
Additional diagnostic: NT device path confirmed as not writable by MSYS2
Environment: Windows 11 Pro 10.0.26200, GNU bash 5.2.37(1)-release (x86_64-pc-msys), Claude Code v2.1.45
I performed independent diagnostics that confirm and extend the root cause analysis above. Key findings:
1. The stdout fd points to a Claude Code task output file via NT device path
By saving fd 1 to fd 5 before redirecting, I was able to inspect the original stdout:
Result:
2. MSYS2 reports the fd as NOT writable
test -w /proc/self/fd/1returns false. This is whyecho(which checks write success) returns exit code 1 — it's the bash builtin's documented behavior: "echo returns 0 unless a write error occurs."3. The NT device path format is the smoking gun
The fd resolves to
C:/Device/HarddiskVolume3/Users/...— this is a Windows NT device path, not a standard Win32 path. MSYS2's POSIX emulation layer cannot handle NT device paths as writable file descriptors. The v2.1.44 pipe-based approach used standard POSIX pipes which MSYS2 translates correctly.4. Complete behavior matrix
| Command | Stdout fd used? | Exit code |
|---------|----------------|-----------|
|
true| No | 0 ||
echo hello| Yes (builtin write to fd 1) | 1 ||
echo hello >&2| Yes (fd 2, same issue) | 1 ||
echo hello > file| No (new fd to file) | 0 ||
ls > /dev/null 2>&1| No (redirected) | 0 |Workaround
Until patched, redirect to file + Read tool:
---
This confirms @chablitzel's analysis: the
spawn()change from pipe-based to file-descriptor-based stdout capture creates an fd that MSYS2 cannot write to, because it inherits a Windows file handle (NT device path) that doesn't translate to a valid POSIX writable fd.It got fixed with the latest update but noooow stop hooks are broken...
● Ran 3 stop hooks ⎿ Stop hook error: Failed with non-blocking status code: c:users34lnst-devtmp_token.json does not exist or is disconnectedlooks like it because path to hooks is messed up
Seems to be a duplicate of https://github.com/anthropics/claude-code/issues/19663.