[BUG] CLI binary path breaks on every VS Code extension update (needs stable path/symlink)

Resolved 💬 4 comments Opened Apr 2, 2026 by Pikauba Closed May 22, 2026

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?

When installing the Claude Code VS Code extension, the claude CLI binary is bundled inside the extension's directory (e.g., ~/.vscode/extensions/anthropic.claude-code-2.1.90-darwin-arm64/bin/claude).

So the ~/.local/bin/claude binary is not there leading command line:

claude --version

To show command not found: claude

Because VS Code creates a new folder with a new version number every time the extension updates, users cannot reliably add this binary to their $PATH or alias it for use in standard external terminals. Once an update occurs, the hardcoded path or alias silently breaks because the old version folder is deleted/replaced. Using a timestamp-based dynamic alias (ls -t) is also brittle and fails if a user rolls back an extension version.

It would be useful not to maintant two claude (one from vscode) and another using the npm, shell or brew installation.

What Should Happen?

To support external terminal usage without forcing users to install a duplicate npm global package, the extension should provide a stable path.

On activation, the extension should either:

  1. Maintain a persistent symlink to the active binary (e.g., at ~/.claude/bin/claude)
  2. Or, automatically generate a dynamic wrapper script in ~/.local/bin/claude that routes to the current active extension folder.

Error Messages/Logs

zsh: command not found: claude
# (Or "no such file or directory" if using a direct alias, occurring immediately after a VS Code background extension update)

Steps to Reproduce

  1. Install the Claude Code VS Code extension.
  2. Locate the bundled binary (e.g., ~/.vscode/extensions/anthropic.claude-code-[VERSION]/bin/claude).
  3. Add this folder to your $PATH or create a .zshrc alias to use the CLI in your standard terminal.
  4. Run claude in your terminal (it works).
  5. Wait for the VS Code extension to update to a newer version (or simulate by renaming the extension folder).
  6. Run claude in your terminal again. The command fails because the referenced folder no longer exists.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.90

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Additional Information

I wrote a robust workaround script for users facing this, which proves how this could be programmatically solved. Instead of guessing the path, this script acts as a permanent wrapper by parsing VS Code's extensions.json as the source of truth to instantly find the currently active claude binary.

If the extension maintainers could bundle a logic similar to this (or automatically write a similar wrapper to the user's local path), it would completely solve the issue:

#!/usr/bin/env bash
set -euo pipefail

EXT_BASE_DIRS=(
  "$HOME/.vscode/extensions"
  "$HOME/.vscode-server/extensions"
  "$HOME/.vscode-server-insiders/extensions"
)

find_from_json() {
  local base="$1"
  local json="$base/extensions.json"

  [ -f "$json" ] || return 1

  if command -v jq >/dev/null 2>&1; then
    jq -r '
      .[]
      | select(.identifier.id=="anthropic.claude-code")
      | .relativeLocation
    ' "$json" | tail -n 1
  else
    grep -A 20 '"id": "anthropic.claude-code"' "$json" \
      | grep '"relativeLocation"' \
      | tail -n 1 \
      | awk -F'"' '{print $4}'
  fi
}

find_from_fs() {
  local base="$1"

  ls -d "$base"/anthropic.claude-code-* 2>/dev/null \
    | sort -V \
    | tail -n 1 \
    | xargs -n1 basename
}

resolve_claude_bin() {
  for base in "${EXT_BASE_DIRS[@]}"; do
    [ -d "$base" ] || continue

    # 1. Try JSON (preferred)
    rel=$(find_from_json "$base" || true)

    if [ -n "${rel:-}" ]; then
      candidate="$base/$rel/resources/native-binary/claude"
      if [ -x "$candidate" ]; then
        echo "$candidate"
        return 0
      fi
    fi

    # 2. Fallback: filesystem scan
    rel=$(find_from_fs "$base" || true)

    if [ -n "${rel:-}" ]; then
      candidate="$base/$rel/resources/native-binary/claude"
      if [ -x "$candidate" ]; then
        echo "$candidate"
        return 0
      fi
    fi
  done

  return 1
}

CLAUDE_BIN=$(resolve_claude_bin || true)

if [ -z "${CLAUDE_BIN:-}" ]; then
  echo "Error: Could not locate Claude binary in any VS Code extension directory" >&2
  exit 1
fi

exec "$CLAUDE_BIN" "$@"

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗