TL;DR
/usr/local/bin/node に昔インストールしたままのNode.js v18が残ってて、Zedがそっちを使ってた。消してシンボリックリンク貼ったら直った。
何が起きたか
ZedでClaude CodeをACP経由で使おうとしたら、こんなエラーが出て起動しなかった。
Server exited with status exit status: 1
file:///Users/{username}/Library/Application%20Support/Zed/node/cache/_npx/xxxxxxxxxxxxxxx/node_modules/@agentclientprotocol/claude-agent-acp/dist/acp-agent.js:6
import packageJson from "../package.json" with { type: "json" };
^^^^
SyntaxError: Unexpected token 'with'
Node.js v18.17.1
「v18.17.1?nvmでv22使ってるのになんで?」ってなった。
環境
- macOS(Apple Silicon)
- Zed 最新版
- Node.js は nvm で管理
原因を探る
まずエラーの意味を理解する
import ... with { type: "json" } はNode.js v20以降の構文。v18では動かない。
でもnode -vしたらちゃんとv22になってる。なんで?
Zedはシェルのパスを引き継がない
ここが罠だった。ZedはGUIアプリとして起動するので、シェルで設定したPATHを完全には引き継がないっぽい。nvmのNodeじゃなくて、システムの固定パスを直接見に行っていたのが原因だった。
犯人はこいつ
find /usr -name "node" -type f
# /usr/local/bin/node
/usr/local/bin/node --version
# v18.17.1
/usr/local/bin/nodeに2023年に手動インストールしたNode.jsがそのまま残ってた。Zedはこっちを使ってた。
試したけどダメだったこと
- nvmでv22に切り替える → ターミナルでは直るがZedには効かない
- settings.jsonに
node.pathを設定する → 効かない - Zedのキャッシュを削除する → 効かない
- Zedをアンインストール・再インストール → 効かない
結局/usr/local/bin/nodeが残っている限りどれも意味がなかった。
解決方法
1. 他に影響がないか確認
grep -r "/usr/local/bin/node" ~/.zshrc ~/.bashrc ~/.bash_profile ~/.zprofile 2>/dev/null
grep -r "#!/usr/local/bin/node" /usr/local/bin/ 2>/dev/null
何も出なければOK。
2. 古いNodeを削除
sudo rm /usr/local/bin/node
sudo rm /usr/local/bin/npm
sudo rm /usr/local/bin/npx
3. nvmのNodeへシンボリックリンクを貼る
削除しただけだとZedが「nodeがない」と言うので、nvmのNodeへシンボリックリンクを貼る。
sudo ln -sf $(which node) /usr/local/bin/node
sudo ln -sf $(which npm) /usr/local/bin/npm
sudo ln -sf $(which npx) /usr/local/bin/npx
4. 確認
/usr/local/bin/node --version
# v22.x.x になってればOK
Zedを再起動したら普通に動いた。
今後nvmでバージョンを変えるとき
シンボリックリンクが古いバージョンを指したままになるので、バージョン変更後にシンボリックリンクも更新する。
nvm install 24
nvm alias default 24
nvm use 24
sudo ln -sf $(which node) /usr/local/bin/node
sudo ln -sf $(which npm) /usr/local/bin/npm
sudo ln -sf $(which npx) /usr/local/bin/npx
まとめ
原因は「昔手動でインストールしたNodeがそのまま残ってた」という完全に自分のせいな話だった。nvmを導入するときにちゃんと掃除しておけばよかった。
ちなみにZedのsettings.jsonでnode.pathを設定しても効かなかったのはZed側の問題な気がする。(違ったら申し訳ないが)