Plugin system overwrites env.PATH with literal ${PATH}, breaking basic shell commands
Bug
When plugins are enabled, the PATH environment variable contains the literal string ${PATH} instead of the expanded system PATH. This causes all standard system commands (open, tr, head, cat, ls, etc.) to be unavailable in Claude Code's Bash tool.
Expected behavior
The PATH set in ~/.claude/settings.json → env.PATH should be respected, and plugin paths should be appended to the resolved PATH — not overwrite it with an unexpanded ${PATH} placeholder.
Actual behavior
Despite having a correct env.PATH in settings.json:
{
"env": {
"PATH": "/Users/me/.local/bin:...:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:..."
}
}
The actual PATH in the Bash tool session becomes:
~/.local/share/mise/shims:${PATH}:/Users/me/.claude/plugins/cache/hyperspell/setup/1.0.0/bin:/Users/me/.claude/plugins/cache/claude-plugins-official/rust-analyzer-lsp/1.0.0/bin:...
${PATH} is a literal string, not expanded. As a result, /usr/bin, /bin, /usr/sbin, /sbin are all missing, and basic macOS commands fail:
$ which open
open not found
$ echo $PATH | tr ':' '\n'
zsh: command not found: tr
Steps to reproduce
- Enable multiple plugins in
settings.json(enabledPlugins) - Set a valid
env.PATHinsettings.json - Start a Claude Code session
- Run
echo $PATHvia the Bash tool — observe${PATH}literal - Run
which open— fails
Environment
- macOS (Darwin 25.4.0, Apple Silicon)
- Shell: zsh
~/.zshenvexists with correct PATH setup (works in regular terminal)- Multiple plugins enabled (superpowers, rust-analyzer-lsp, typescript-lsp, slack, etc.)
Workaround
Use absolute paths (e.g., /usr/bin/open) in Bash tool calls, or run commands in a regular terminal instead of via ! prefix in Claude Code.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗