[BUG] Bash tool leaves 0-byte stray files in the working directory when commands contain shell metacharacters from source code (Windows / Git Bash)
Environment
- OS: Windows 11
- Shell: Git Bash (MINGW64) — Claude Code's Bash tool
- Symptom seen across multiple C#/.NET projects (cwd = project root)
Summary
While Claude Code works on a codebase, the Bash tool intermittently creates 0-byte files in the working directory whose names are fragments of the project's own source code, e.g.:
!IsRefreshing
string.IsNullOrEmpty(code)
SaveTabOrder()
_timer.Stop()
_settings.LoadLogin().ChartAutoLoginPassword)
token)
0
They accumulate over a session (dozens+), are 0 bytes, and reappear in every project the agent touches. This looks like the same class as #23942 (literal NUL files) and #17087 (0-byte dotfiles created by the Bash tool), but here the filenames are C# expressions.
Root cause (reproduced)
When a command run through the Bash tool contains an unquoted C# > / => / , — or an analysis pipeline that redirects to a target derived from matched source — Git Bash interprets it as an output redirection and creates a file named after the following token. Reproduced deterministically in plain Git Bash on Windows:
# pattern 1 — unquoted lambda/comparison in a command
mkdir /tmp/t1 && cd /tmp/t1
grep -rn public bool X => !IsRefreshing src # '> !IsRefreshing' → creates file "!IsRefreshing"
ls # -> !IsRefreshing
# pattern 2 — analysis loop redirecting to a code-derived (quoted) target
mkdir /tmp/t2 && cd /tmp/t2
printf 'public bool IsInvalid => string.IsNullOrEmpty(code);\npublic void SaveTabOrder(){ _timer.Stop(); }\n' > s.cs
grep -oE '[A-Za-z_.]+\([^)]*\)' s.cs | while read -r m; do : > "$m"; done
ls # -> "SaveTabOrder()", "_timer.Stop()", "string.IsNullOrEmpty(code)"
(Confirmed the stray files are created by the Bash tool's subprocess, cwd = project; not by any host/editor. They persist and pollute git status.)
Expected
Bash tool commands should not silently pollute the working directory with stray files. Options: run in a manner where an accidental redirect target can't land in the user's repo, warn/strip when a command's redirect target is not an intended path, or (as with #23942's > NUL) fix internal command construction.
Actual
0-byte garbage files named after source fragments accumulate in the repo root every session.
Related: #23942, #17087, #25968, #28874, #4206