Claude Code Bash tool returns no output on Windows: Git's bash.exe was the WSL launcher

Claude Code on Windows: why my commands came back empty for six months (bash.exe was the WSL launcher)

For about six months, the shell commands Claude Code ran on my Windows PC came back with no output and exit code 1. The cause was one file. C:\Program Files\Git\bin\bash.exe turned out to be the Microsoft "Bash Launcher" for WSL, an 86,016-byte file dated January 2025. I renamed it out of the way, copied Git's own sh.exe into its place as bash.exe, and the output came back.

If you only want the check and the fix, skip to "Check your own bash.exe." The rest is how I found it and the two Windows traps I hit while fixing it.

What I saw: two error lines at every login

I don't write code. I describe what I want and Claude Code runs the commands.

These two lines appeared every time I started a session:

SessionStart:startup hook error
Failed with non-blocking status code: No stderr output

"No stderr output" means the failing program didn't even leave an error message. I asked Claude Code to trace where those two lines came from.

The trail: one plugin hook, one shell

The error belonged to a single plugin. Its startup hook ran a shell script with bash. My global and project settings had no startup hook of their own, so that plugin was the only suspect.

The script itself was fine. When we ran bash directly, it printed garbled output containing Bash/Service/E_UNEXPECTED and quit with exit code 1.

Claude Code's own Bash tool uses the same bash.exe. My session history showed that tool had been returning empty output with exit 1 since March 2026. The startup hook showed an error, while the Bash tool had been returning no output for half a year.

The cause: Git's folder held the wrong bash.exe

On my PC, C:\Program Files\Git\bin contained bash.exe, git.exe and sh.exe. git.exe and sh.exe were Git's normal wrappers, dated February 2026. bash.exe was different. Its file description said "Microsoft Bash Launcher", it was 86,016 bytes, and it was dated 2025-01-29.

So anything that called Git\bin\bash.exe got the WSL launcher instead, and the launcher failed in that setting. WSL itself (Ubuntu) was installed normally and worked through the wsl command. Git's other bash, usr\bin\bash.exe (version 5.2.37), was also fine. Only the one in bin was wrong.

How a WSL file ended up in Git's folder, I still don't know. It happened sometime before March, and I have no record of it.

Check your own bash.exe

Open PowerShell and run:

(Get-Item 'C:\Program Files\Git\bin\bash.exe').VersionInfo.FileDescription

If it prints something with "Git for Windows" in it, this isn't your problem. If it prints "Microsoft Bash Launcher", you have the same swap I had.

If Claude Code's Bash tool goes silent again, this is the first thing I'll check.

The fix (and the two traps on the way)

The plan was simple: take the launcher out and put Git's wrapper back. sh.exe in the same folder is that wrapper, so a copy of it named bash.exe does the job.

Trap 1: my antivirus blocked delete and overwrite, even as admin. My PC runs McAfee. In an elevated PowerShell window, both Remove-Item on the file and Copy-Item -Force over it returned "Access denied". Renaming the file worked. So the order that worked was:

  1. Rename bash.exe to bash.exe.old_wsl (same folder).
  2. Copy sh.exe to bash.exe. The new file was 47,008 bytes.
  3. Move the old file out of Program Files to a folder on the same drive, then delete it from an elevated window.

Trap 2: an inline admin command can fail without a word. Running the elevated step as a one-liner with Start-Process -Verb RunAs -Command "..." broke the quotes on the way into the new window. It exited with 0 and wrote an empty log, so it looked like success, and nothing had changed. Putting the commands in a .ps1 file and calling it with -File worked.

After the swap, Git's bash.exe -c reported MINGW64 and bash 5.2.37. The plugin's hook script exited 0, and Claude Code's Bash tool printed output again. My Git\bin folder now holds exactly three files: bash.exe, git.exe, sh.exe.

The next login showed one normal line from the plugin (Ready — 4 sources active) instead of the two error lines.

One file, two symptoms

The same broken file caused both the startup error and the empty Bash tool. The error message said "non-blocking", and the empty tool output didn't say anything at all.
(My Task Scheduler post was also about Windows quietly running the wrong program, a fake python that time. Windows seems to enjoy this joke.)

FAQ

Why does Claude Code's Bash tool return nothing on Windows?
In my case, the bash.exe in C:\Program Files\Git\bin had been replaced by the WSL launcher. Check its file description with the PowerShell line above. If it isn't Git for Windows, that's a strong lead.

What does "SessionStart:startup hook error ... No stderr output" mean?
A startup hook failed and the failing program printed no error message. Mine came from one plugin's hook that ran bash. Find which hook runs at startup, then run its command by hand to see what actually fails.

Why can't I delete or replace a file in Program Files, even as admin?
On my PC, the antivirus (McAfee) blocked delete and overwrite of program files. Rename was allowed. Rename the file aside, copy the new one in, move the old one out of Program Files to the same drive, then delete it from an elevated window.

Is WSL broken if this happens?
Not in my case. My WSL (Ubuntu) was installed normally and worked through the wsl command. The problem was a WSL launcher file sitting where Git's bash should be.

Comments

Popular posts from this blog

Python script works manually but not in Task Scheduler: the Microsoft Store python stub (and a daily alive check)

Schedule a weekly AI summary with Windows Task Scheduler (with a human OK step)

Codex vs Claude Code: which jobs I give each (3 months of work logs)

What not to automate with AI: my approval rule for money and irreversible actions

Telegram bot receives /start automatically: how it triggered my kill switch (one-line fix)