[BUG] Shell snapshot exports PATH with single-quoted ${PATH}, preventing expansion
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?
The shell snapshot Claude Code generates at startup (~/.claude/shell-snapshots/snapshot-zsh-*.sh)
exports PATH using single quotes around ${PATH}. Single quotes prevent shell expansion, so
${PATH} is written into the new PATH as the literal 7-character string ${PATH} instead of being
replaced with the previous PATH value.
Offending line from the snapshot:
``bash``
export PATH='/Users/USER/.local/share/mise/installs/ruby/3.4.2/bin:${PATH}:/Users/USER/.claude/plugins/
cache/claude-plugins-official/playwright/unknown/bin:/Users/USER/.claude/plugins/cache/claude-plugins-o
fficial/github/unknown/bin:/Users/USER/.claude/plugins/cache/claude-plugins-official/code-review/unknow
n/bin:/Users/USER/.claude/plugins/cache/claude-plugins-official/figma/2.1.7/bin:/Users/USER/.claude/plu
gins/cache/claude-plugins-official/atlassian/9b52fb18e184/bin:/Users/USER/.claude/plugins/cache/claude-
plugins-official/sentry/1.0.0/bin:/Users/USER/.claude/plugins/cache/claude-plugins-official/ruby-lsp/1.
0.0/bin:/Users/USER/.claude/plugins/cache/claude-plugins-official/superpowers/5.0.7/bin:/Users/USER/.cl
aude/plugins/cache/claude-plugins-official/chrome-devtools-mcp/latest/bin'
After this runs, PATH becomes ruby/bin:${PATH}:plugin1:plugin2:… — everything the user had in
PATH before (including /bin, /usr/bin, /opt/homebrew/bin, ~/.local/bin, etc.) is gone.
Two visible consequences:
- Bash tool is crippled — basic system utilities (
ls,grep,tr,head,zsh) fail with
"command not found" because /bin and /usr/bin are no longer in PATH.
- False "native install" warning on startup. Claude Code prints:
> Native installation exists but ~/.local/bin is not in your PATH. Run: echo 'export
PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
This persists even when ~/.local/bin is verifiably in the interactive shell's PATH (confirmed by
running echo $PATH | tr ':' '\n' | grep local/bin — three hits). The native-install detector appears
to rely on the same broken snapshot.
Environment:
- Claude Code 2.1.113
- macOS (Darwin 25.3.0)
- zsh + oh-my-zsh + mise
- Native install at
~/.local/bin/claude - Enabled plugins: playwright, github, code-review, figma, atlassian, Notion, sentry, ruby-lsp,
superpowers, chrome-devtools-mcp
What Should Happen?
The snapshot should set PATH to a value that actually contains the user's pre-existing PATH
entries, so system utilities and user-installed binaries remain available inside the Bash tool.
Either of these is correct:
- Use double quotes and keep
$PATHunquoted for expansion:
``bash``
export PATH="/…/ruby/bin:$PATH:/…/plugin1:/…/plugin2"
- Or, better: fully expand
PATHat snapshot-generation time and write the final value as a literal
string, so the snapshot isn't dependent on the environment in which it's later sourced.
With the fix in place:
ls,grep,zsh,head,tr, etc. should resolve in Bash tool calls.- The "native install is not in your PATH" warning should not appear when
~/.local/binis on the
user's actual PATH.
Error Messages/Logs
Startup warning (persists even when `~/.local/bin` is already on the user's interactive `PATH`):
Native installation exists but ~/.local/bin is not in your PATH. Run:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
Example Bash tool failures inside a session:
$ zsh -c 'echo $PATH' | tr ':' '\n' | grep local/bin
zsh: command not found: grep
zsh: command not found: zsh
zsh: command not found: tr
$ ls ~/.claude
zsh: command not found: ls
Echoing `$PATH` inside a Bash tool call shows the literal `${PATH}` sitting in the middle of the value:
/Users/USER/.local/share/mise/installs/ruby/3.4.2/bin:${PATH}:/Users/USER/.claude/plugins/cache/claude-
plugins-official/playwright/unknown/bin:…
Steps to Reproduce
- macOS with zsh as the login shell. (In my setup: oh-my-zsh + mise, but the bug is in the quote style
of the snapshot, not shell-config-specific.)
- Install Claude Code via the native installer so the binary lives at
~/.local/bin/claude. - Enable several official plugins, e.g.
playwright,github,code-review,figma,atlassian,
Notion, sentry, ruby-lsp, superpowers, chrome-devtools-mcp.
- Start
claudein any directory. - Observe the startup warning: "Native installation exists but
~/.local/binis not in your PATH."
— even though echo $PATH | tr ':' '\n' | grep local/bin in the same terminal prints the directory.
- Inside the session, ask Claude to run
ls ~/.claudeorzsh -c 'echo $PATH' | grep local/binvia
the Bash tool. You'll get command not found for ls, zsh, grep, tr, head, etc.
- Open
~/.claude/shell-snapshots/snapshot-zsh-*.sh(the most recent one) and search for `export
PATH=. The assignment uses single quotes and contains the literal string ${PATH}` in the middle of
the value.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.13
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗