Claude Codeがasdfのshimで古いバージョンを掴み続ける問題を直す
asdfでNode.jsを管理する環境ではnpm版からネイティブ版へ切り替えてもclaude --versionが古いままのことがあります。原因はasdfのshimで、npm版の削除とasdf reshimで直します。
asdfでNode.jsのバージョンを管理している環境で、npm版からネイティブ版のClaude Codeへ切り替えてもclaude --versionが古いままなら、原因はasdfのshimです。~/.asdf/shimsがPATHの先頭に入っていて、そこに古いnpm版のclaudeが残っています。直し方は、該当するNode.jsバージョンでnpm uninstall -g @anthropic-ai/claude-codeを実行し、asdf reshimでshimを作り直すことです。
症状: ネイティブ版に切り替えたのにclaude --versionが古いまま
Claude Codeのネイティブインストーラーは、macOS/Linuxで実行ファイルを~/.local/bin/claudeに置きます。npmインストールはnpm install -g @anthropic-ai/claude-codeで、同じネイティブバイナリを@anthropic-ai/claude-codeパッケージ経由で導入する仕組みです。
asdf管理下のNode.jsで先にnpmグローバルインストールしていた環境では、この2つが両方PATH上に存在した状態になります。which -a claudeを実行すると、asdfのshimが先頭に、ネイティブ版のパスがその後ろに並びます。シェルは先頭のパスを実行に採用するため、ネイティブ版へ切り替えたつもりでもshim側の古いバージョンが動き続けます。
この状況はよくある経路で起こります。asdfでNode.jsのバージョンを揃えているチームで、Claude Codeを試すためにnpm install -g @anthropic-ai/claude-codeを実行し、そのままインストール方法を意識せず使い続けるケースです。後日ネイティブインストーラーへ切り替えても、asdf側の古いnpmパッケージは削除されないまま残ります。
which -a claudeたとえば次のような並びになった場合、PATHの前方にあるshimが常に優先されます(実際のパスは環境によって変わります)。
/Users/you/.asdf/shims/claude
/Users/you/.local/bin/claude複数のインストール手段が競合していないかを一般的に確認する手順はClaude Codeのcommand not foundの直し方にまとめてあります。ネイティブ・レガシーnpm・グローバルnpmの3経路はそちらの記事で扱っており、asdfのshimはこの3経路のさらに外側で起きる問題です。
asdfのshimがPATHの前方を占有する仕組み
asdfは管理下の実行ファイルをすべて~/.asdf/shims配下のshimに置き換え、このディレクトリをPATHの先頭に加えます。同名の実行ファイルが他の場所にあっても、シェルは常にshimを先に見つけます。「shim」はasdf execを呼ぶだけの薄いラッパーで、実際にどのバージョンを起動するかは.tool-versionsファイルを見て解決します。
npmでグローバルインストールした実行ファイルもこの対象です。asdfの公式FAQは、管理下のツールが提供する実行ファイルと既存の実行ファイルの名前が衝突するケースを取り上げ、該当パッケージを削除するのが最善だとしています。asdf which <command>はその特定に使えます。npm経由でグローバルインストールしたclaudeは、インストール時にアクティブだったNode.jsバージョンの配下に紐づいてshimが作られます。今どのバージョンが有効かはasdf currentで確認できます。
shimの中身を確認する — どのバージョンが古いclaudeを握っているか
asdf shimversions <command>は、そのコマンドのshimを提供しているプラグインとバージョンの一覧を表示します。nodeやnpmのような実行ファイルを対象にした例が公式ドキュメントに載っており、任意のshim対象コマンドに使えます。
asdf which <command>はshimの先にある実際の実行ファイルのパスを表示します。組み合わせると、どのNode.jsバージョンの下でnpmインストールしたclaudeが古いまま残っているかを直接特定できます。
asdf shimversions claude
asdf which claudeasdf shimversions claudeが示したバージョンが、そのままnpmアンインストールで指定すべきNode.jsバージョンです。たとえばnodejs 20.11.0が返ってきた場合、そのバージョンがnpmグローバルインストールでclaudeを提供している対象です(実際の値はインストール履歴によって変わります)。
shimが指す実体そのものを覗きたい場合はasdf where nodejs <バージョン>も使えます。そのバージョンのインストール先ディレクトリを表示するコマンドで、配下のnpmグローバル用ディレクトリにclaudeの実行ファイルが本当に残っているかを直接確認できます。
直し方: 古いnpmグローバル版を消してshimを再生成する
直し方は3手順です。まずasdf shimversions claudeが示したNode.jsバージョンを、現在のシェルだけに一時的に効かせます。次にそのバージョン配下でnpm uninstall -g @anthropic-ai/claude-codeを実行し、パッケージ自体を削除します。最後にasdf reshim nodejs <バージョン>を実行し、そのバージョンのshim一覧を実行ファイルの現状に合わせて作り直します。
一時的な切り替えにはASDF_${TOOL}_VERSION形式の環境変数を使います。これは.tool-versionsファイルより優先され、設定したシェルセッションの中だけで効きます。プロジェクトの.tool-versionsをasdf setで書き換えると他の用途にも影響するため、後片付けだけが目的のこの場面では環境変数で一時的に上書きする方が安全です。この上書きは特に元に戻す操作が要りません。環境変数はエクスポートしたシェルセッションが終われば消え、以降のセッションは通常どおり.tool-versionsやasdfのデフォルト設定に従います。
asdf reshimは対象バージョンのshimを再計算する処理です。npm CLIでグローバルインストールした実行ファイルは、プラグインのインストール処理を経由していないため、reshimを実行するまで新しいshimが作られません。逆に、アンインストール後にreshimを実行すれば、もう存在しないclaude用のshimは新しい一覧から外れます。
ASDF_NODEJS_VERSION=20.11.0 npm uninstall -g @anthropic-ai/claude-code
asdf reshim nodejs 20.11.0シェルはコマンドの場所を一度解決するとキャッシュします。変更を反映するには新しいターミナルを開くか、bashならhash -r、zshならrehashを実行します。
hash -r
which -a claude
claude --version
claude doctor仕上げにwhich -a claudeを実行し、~/.local/bin/claudeだけが残っていることを確認します。claude doctorは直近の自動更新の結果も表示するので、ネイティブ版が正しく起動しているかどうかの最終確認に使えます。reshim後にasdf which claudeを実行してエラーになれば、そのバージョン配下にはもうclaudeのshimが無いということです。エラーが出ない場合は、まだ別のNode.jsバージョンにも古いインストールが残っている可能性があります。
それでもreshimが効かない場合
ここまでの手順を実行しても症状が変わらないときは、シェル設定ファイルの中でasdf.sh(fishならasdf.fish)をsourceしている行の位置を疑います。asdfの公式FAQは、asdf reshimで解決しない場合の多くが、.bash_profileや.zshrcなどの設定ファイルでこの行が末尾に置かれていないことだとしています。$PATHを設定する行や、oh-my-zshのようなフレームワークを読み込む行より後ろに置く必要があります。初期化行を設定ファイルの末尾へ移動し、新しいターミナルを開いてからwhich -a claudeを確認し直します。
PATHの並び自体を書き換えて~/.local/binをasdfのshimsより前に置く方法もあります。ただし.zshrcなどでasdfの初期化行より前にこの一行を書くと、次に開くターミナルではasdfの初期化が後から実行され、結局shimsのパスに上書きされます。初期化行より後に書けば並びは維持できますが、その場合でもshimの元になっている古いnpmパッケージ自体は残ったままです。パッケージを消せば、並び順に頼らずに済みます。
asdfの公式ドキュメントは、shimそのものを迂回する手段としてasdf-direnvプラグインも挙げています。プロジェクトのディレクトリに入った時点で環境変数を自動設定する仕組みで、shim経由の解決を避けたい場合やディレクトリごとに切り替えたい場合に使えるとしています。ただし別プラグインの追加導入が前提になるため、今回のようにnpmグローバル版を消すだけで直る単純なケースでは、reshimの方が手数が少なく済みます。
補足: v2.1.47でdoctorのmise/asdf誤分類が修正された
Claude Codeのclaude doctorは、mise管理下とasdf管理下のインストールをどちらもネイティブインストールと誤分類していたバグを、v2.1.47(2026年2月18日公開)で修正しました。Anthropicはリリースノートでmiseとasdfの両方を名指ししています。
v2.1.47以降ならclaude doctorの分類表示自体は信頼できます。ただし分類が正しく表示されても、PATH上でどちらの実行ファイルが実際に起動するかは別問題です。
外部ツールの実行パスをasdfやmiseの外側で固定する発想は、sandbox.socatPathでLinux/WSL2のsocatパスを固定する記事でも扱っています。環境変数がらみの別のつまずきとしては、Claude Codeが.envをBash環境へ読み込んでいた問題も参考になります。
asdfとネイティブインストーラーを併用する運用は同じ現象を繰り返す
npmグローバル版を消して直しても、この運用を続ける限り再発します。後日別のプロジェクトでasdf set nodejsを使って別バージョンに切り替え、そこでうっかりnpm install -g @anthropic-ai/claude-codeをもう一度実行すれば、新しいバージョンのNode.js配下に同じ名前のshimが再び作られます。
ネイティブインストーラーは~/.local/bin/claudeをバックグラウンドで自動更新します。asdfのshim経由で起動している限り、この自動更新の恩恵はそもそも届きません。起動しているのはNode.js配下に固定されたnpmパッケージのバージョンで、更新するには手動でnpm install -g @anthropic-ai/claude-code@latestを打つ必要があります。
Node.jsのバージョン固定そのものが目的でない限り、Claude Codeの実行ファイルは一度もasdfの管理対象に入れないのが実務上シンプルな運用です。ネイティブインストーラーだけに揃えておけば、この種の巻き戻りをそもそも避けられます。