Skip to content

Desktop app shell snapshot writes process.env.PATH instead of resolved shell PATH #43800

@m-shibusawa0121

Description

@m-shibusawa0121

Summary

The desktop app's shell snapshot generation writes export PATH=... using the JavaScript process's PATH (minimal macOS GUI app PATH: /usr/bin:/bin:/usr/sbin:/sbin) instead of the PATH resolved inside the zsh process after sourcing dotfiles (.zshenv, .zshrc, etc.).

This causes tools installed via Homebrew (/opt/homebrew/bin) and /usr/local/bin to be unavailable in Bash tool executions.

Environment

  • macOS (Apple Silicon)
  • Claude Code Desktop App v2.1.87
  • Shell: zsh

Steps to Reproduce

  1. Install tools via Homebrew (e.g., node, gh, npm)
  2. Add /opt/homebrew/bin to PATH in ~/.zshenv:
    export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
  3. Launch Claude Code desktop app (not terminal)
  4. Run which node via Bash tool → command not found

Root Cause

In the snapshot generation code (gW7 / G31 functions), the shell script template includes:

echo "export PATH=${W7([H || ""])}" >> "$SNAPSHOT_FILE"

This evaluates H (a JavaScript variable from process.env.PATH) at template build time, not the PATH that the zsh process resolves after sourcing .zshenv / .zshrc.

The snapshot generation runs zsh -c -l <script>, which does correctly source .zshenv and resolve the full PATH inside zsh. However, that resolved PATH is never captured — the snapshot file gets the JavaScript-side value instead.

Expected Behavior

The snapshot should capture the PATH as resolved inside the zsh process after all dotfiles are sourced, not the parent JavaScript process's PATH.

Current Workaround

Using a SessionStart hook in settings.json to patch the snapshot file after generation:

{
  "hooks": {
    "SessionStart": [{
      "hooks": [{
        "type": "command",
        "command": "sleep 1; SNAP=$(ls -t ~/.claude/shell-snapshots/snapshot-zsh-*.sh 2>/dev/null | head -1); if [ -n \"$SNAP\" ] && grep -q 'export PATH=/usr/bin' \"$SNAP\" && ! grep -q '/opt/homebrew/bin' \"$SNAP\"; then sed -i '' 's|export PATH=/usr/bin|export PATH=/usr/local/bin\\\\:/opt/homebrew/bin\\\\:/usr/bin|' \"$SNAP\"; fi",
        "timeout": 10
      }]
    }]
  }
}

Additional Notes

  • settings.json's env.PATH setting is also ineffective because the snapshot's export PATH=... overrides it when sourced.
  • The terminal version of Claude Code inherits the correct PATH from the parent shell, so this issue is specific to the desktop app.

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions