Windows: Git Bash shell-snapshot embeds raw Windows PATH unconverted, breaking short-name command resolution

Open 💬 1 comment Opened Jul 1, 2026 by SentoCatala

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Environment: Windows 11, Claude Code using Git Bash as the shell for the Bash tool.

Every Bash tool call resolves bare command names to "command not found" — ls, grep, rm, pwsh, python, python3, etc. all fail — while invoking the exact same binaries by absolute path (e.g. /c/Program Files/PowerShell/7/pwsh.exe) works fine.

Root cause: Claude Code generates a shell snapshot per process start at ~/.claude/shell-snapshots/snapshot-bash-<timestamp>-<id>.sh, which is sourced on every Bash tool invocation. This snapshot contains a line like:

export PATH='C:\Windows\system32;C:\Windows;...;C:\Program Files\PowerShell\7\;...:/c/Users/<user>/AppData/Roaming/Claude/local-agent-mode-sessions/.../bin'
i.e. the native Windows PATH (semicolon-separated, drive-letter paths like C:\...) is captured verbatim, without conversion to POSIX form, then some additional already-POSIX plugin bin directories are appended with :. Since bash's PATH parsing splits on :, and every Windows path segment contains a : right after its drive letter (C:\...), the entire PATH gets shredded into meaningless fragments — so name-based PATH lookup can never succeed for any entry, Windows or POSIX.

What does NOT fix it (all tested, no effect):

Setting a corrected POSIX PATH under env in settings.json (global ~/.claude/settings.json) — other new keys added under the same env (e.g. a custom BASH_ENV) do propagate correctly into the spawned bash process, confirmed by reading them back inside a Bash tool call — but PATH itself is always re-exported by the snapshot regardless.
Adding PATH-fix logic to ~/.bashrc / ~/.bash_profile.
Setting BASH_ENV to point at a repair script — confirmed the env var reaches the process, but the script is never sourced (no side effect from a debug marker written by the script).
Restarting the app (twice) and killing a lingering background process — a new snapshot file is generated each time, but it always re-captures the same broken raw Windows PATH.
Confirmed workaround (session-scoped only): manually editing the current snapshot's export PATH=... line to a cygpath -up-converted equivalent (using Git's own usr/bin/cygpath.exe), and prepending Git's usr/bin (coreutils aren't present in the native Windows PATH at all, so they're missing from the captured value too), immediately fixes command resolution for the rest of that process's lifetime.

What Should Happen?

When generating shell-snapshots/snapshot-bash-*.sh on Windows, Claude Code should run the captured PATH through a Windows→POSIX path-list conversion (equivalent to cygpath -up) before writing the export PATH=... line, and ensure Git's usr/bin (and mingw64/bin) are included even though they aren't part of the native Windows PATH. With that fix, short-name commands (ls, grep, pwsh, python, etc.) should resolve correctly in every new Bash tool session without any manual workaround.

Error Messages/Logs

Steps to Reproduce

On Windows, use Claude Code with Git Bash as the shell for the Bash tool (default on Windows installs with Git for Windows present).
Start a Claude Code session and run any short-name command through the Bash tool that isn't a shell builtin, e.g.:
ls
pwsh -Command "echo ok"
python --version
grep --version
Observe the result: bash: ls: command not found, bash: pwsh: command not found, etc., even though these binaries are installed and present in the user's Windows PATH.
Confirm the binaries do work when invoked by absolute path, e.g.:
/c/Program Files/PowerShell/7/pwsh.exe -Command "echo ok"
This succeeds, proving the binaries and permissions are fine — only name-based PATH resolution fails.
Inspect ~/.claude/shell-snapshots/ and open the most recently modified file matching snapshot-bash-*.sh. Find the line starting with export PATH='...'. Note that its value is the raw, semicolon-separated native Windows PATH (e.g. C:\Windows\system32;C:\Windows;...;C:\Program Files\PowerShell\7\;...), not a POSIX colon-separated form.
(Optional, to rule out a settings.json misconfiguration) Add a new custom key, e.g. "TEST_VAR": "hello", under env in ~/.claude/settings.json, restart, and run echo $TEST_VAR via the Bash tool — it correctly prints hello, showing that env overrides do propagate to the Bash tool's process. Now try setting "PATH" to a corrected POSIX value the same way — restart and repeat step 5: the snapshot's export PATH=... line still contains the raw unconverted Windows value, unaffected by the env.PATH setting.
Restart the Claude Code application and repeat step 2. A brand-new file appears in ~/.claude/shell-snapshots/ with a new timestamp, but it again contains the same unconverted, broken PATH — the bug reproduces on every fresh session/process start.

Claude Model

None

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

Claude 1.17377.1 (2b3ab4) 2026-06-30T20:11:42.000Z

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗