
1. npm ENOTEMPTY 报错到底卡在哪一步claude-code 全局安装失败的真实场景npm error code ENOTEMPTY配合syscall rename和directory not empty是 Node.js 全局包升级时最典型的文件系统级冲突。它跟网络超时、版本不兼容完全不是一类问题——npm 已经下载完了新包只是在替换旧目录的最后一步被挡住了。理解这一点排查方向就不会跑偏。报错长这样npm error code ENOTEMPTY npm error syscall rename npm error path /opt/homebrew/lib/node_modules/anthropic-ai/claude-code npm error dest /opt/homebrew/lib/node_modules/anthropic-ai/.claude-code-2DTsDk1V npm error errno -66 npm error ENOTEMPTY: directory not empty, rename /opt/homebrew/lib/node_modules/anthropic-ai/claude-codenpm 安装全局包的流程分三步先把旧版本目录重命名成一个带随机后缀的临时目录比如.claude-code-2DTsDk1V再把新版本写进原路径最后删掉临时目录。rename系统调用要求目标目录为空或不存在一旦旧目录里有 npm 管不到的文件——被进程占用的.node文件、root 权限写入的缓存、编辑器生成的临时文件——重命名就会失败errno -66 直接抛出。哪些人最容易撞上这个错我整理了几类高频场景场景触发原因典型表现Homebrew 装 Node 后升级/opt/homebrew/lib/node_modules权限受 brew 管理反复npm install -g都报同一路径切换 Node 版本nvm/fnm旧版本全局目录残留新版本 prefix 指向不同换版本后首次安装必报多账号或配置被改安装中途 CtrlC临时目录没清干净报错路径带.claude-code-xxxx后缀企业内网/CI 环境缓存层复用导致旧目录未清偶发重跑有时能过曾用 sudo 安装目录属主变成 root普通用户删不掉ls -la看到 owner 是 root判断自己属于哪一类最快的办法是看报错里的path和dest。如果dest已经存在且非空说明上一次安装中断留下了临时目录如果path本身删不掉多半是权限或进程占用。这里有个容易被忽略的点很多人第一反应是npm install -g anthropic-ai/claude-code --force但--force只跳过部分校验不会帮你删掉被占用的文件。真正要解决的是「谁占着这个目录」和「谁有权删这个目录」。还有一个认知误区值得说清楚。ENOTEMPTY 不是 claude-code 独有的问题任何全局 npm 包在升级时都可能遇到只是 claude-code 更新频繁、体积不小撞上的概率更高。所以下面这套排查思路换成openai/codex、google/gemini-cli一样适用。我在一台 M 系列 Mac 上复现过完整过程先用 Homebrew 装 Node 20npm install -g anthropic-ai/claude-code成功然后nvm install 22 nvm use 22再装同一个包立刻报 ENOTEMPTY路径正是/opt/homebrew/lib/node_modules/anthropic-ai/claude-code。原因很清楚——nvm 切换后npm config get prefix变了但旧目录还在原地npm 尝试重命名时发现里面有 brew 写入的只读文件。所以排查顺序建议固定为先确认进程没占用再确认权限归属最后才动缓存。顺序反了会白折腾。2. 修完 ENOTEMPTY 之后用 TaoToken 统一 Key 通道接管 claude-code 的模型请求目录清理只是让 claude-code 能装上装完之后你还要面对第二个问题模型请求走哪条通道。默认情况下 claude-code 会读环境变量里的 Anthropic 相关配置如果你同时用 Codex、Cline、Cursor 好几个工具每个都配一遍 Key管理成本很高而且一旦某个 Key 额度用完得挨个改。TaoToken 在这里的角色是统一入口。它提供一个兼容 Anthropic 接口规范的 Base URL你把 claude-code 的请求指向它再用一个 Key 管理所有模型的调用。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数配置时别多写。为什么要在修完 ENOTEMPTY 之后立刻做这件事因为 claude-code 的配置文件和 npm 全局目录是两套东西。你rm -rf删掉的是/opt/homebrew/lib/node_modules/anthropic-ai/claude-code但用户级配置在~/.claude/settings.json或项目级.claude/settings.json删包不会动它。如果之前配置写错了重装多少次都没用。反过来先把 Key 通道理顺再验证安装能少走一轮弯路。TaoToken 适合谁三类人最明显一是同时用多个 AI 编码工具、想统一管 Key 的二是团队里需要共享一套调用额度、又不想每人发 Key 的三是经常切换模型做对比测试、不想每次改环境变量的。需要说清楚的是TaoToken 不是编辑器也不替代 claude-code 本身。它是请求转发层claude-code 还是那个 claude-code只是它发出的模型请求不再直连而是先到 TaoToken 再分发。这个定位搞混了后面配置会一头雾水。拿到 Key 的路径进 https://taotoken.net/api-keys 登录后创建 API Key复制出来。这个 Key 后面要填进 settings.json 的env字段里。如果你还没决定用哪个模型可以先到 https://taotoken.net/models 看一眼可用列表再决定 Model ID 填什么。有一点必须提醒Key 只显示一次创建后立刻复制保存。丢了只能重建重建后旧 Key 立即失效所有引用它的配置文件都要同步更新。我见过有人把 Key 写进 Git 仓库然后推到公开分支这种操作等于把额度白送人务必用环境变量或本地配置文件承载。3. 可复制配置settings.json 骨架 npm 目录清理命令这一节给两段能直接抄的东西。第一段是 claude-code 的 settings.json 配置骨架第二段是 ENOTEMPTY 的清理命令。两段配合用先清目录再写配置。先看 settings.json。claude-code 支持用户级和项目级配置用户级路径是~/.claude/settings.json项目级是项目根目录下的.claude/settings.json。项目级优先级更高适合给不同项目配不同模型。骨架如下{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-20250514 }, permissions: { allow: [], deny: [] } }三个字段的作用要分清ANTHROPIC_BASE_URL决定请求发到哪填 TaoToken 的 API 地址ANTHROPIC_AUTH_TOKEN是鉴权凭证填你在 api-keys 页面创建的 KeyANTHROPIC_MODEL指定默认模型具体可用的 Model ID 到 https://taotoken.net/models 查别照抄我这里的示例值模型会更新。如果你用 Codex配置在~/.codex/auth.json结构不同但三件套一样——Base URL、Key、Model ID 缺一不可{ OPENAI_BASE_URL: https://taotoken.net/api, OPENAI_API_KEY: sk-你的TaoToken密钥, OPENAI_MODEL: gpt-4o }Cline 或 Roo Code 这类 VS Code 插件配置在插件设置面板里同样是填 Base URL、API Key、Model ID 三项。Cline 的 MCP 配置如果单独走记得 MCP server 的地址和模型请求地址是两回事别混填。现在看 ENOTEMPTY 的清理命令。核心思路是先停进程再删目录再清缓存最后重装。按顺序执行# 1. 确认没有 claude 进程占用 ps aux | grep claude # 2. 有的话先结束macOS/Linux pkill -f claude # 3. 进入报错路径的父目录 cd /opt/homebrew/lib/node_modules/anthropic-ai/ # 4. 删除旧目录和所有临时目录 rm -rf claude-code rm -rf .claude-code-* # 5. 清 npm 缓存 npm cache clean --force # 6. 重新安装 npm install -g anthropic-ai/claude-codelatest如果你的 prefix 不是 Homebrew 路径用这条命令查真实路径把上面第 3 步替换掉npm config get prefix # 输出类似 /usr/local 或 ~/.npm-global # 则目录是 prefix/lib/node_modules/anthropic-ai/权限问题导致的删不掉先修属主再删sudo chown -R $(whoami) $(npm config get prefix)/lib/node_modules/anthropic-ai/ rm -rf $(npm config get prefix)/lib/node_modules/anthropic-ai/claude-code rm -rf $(npm config get prefix)/lib/node_modules/anthropic-ai/.claude-code-*Windows 上用 PowerShell管理员身份运行Remove-Item -Recurse -Force $env:APPDATA\npm\node_modules\anthropic-ai\claude-code Remove-Item -Recurse -Force $env:APPDATA\npm\node_modules\anthropic-ai\.claude-code-* npm cache clean --force npm install -g anthropic-ai/claude-codelatest一劳永逸的做法是配置用户级全局目录避开系统目录的权限坑mkdir -p ~/.npm-global npm config set prefix ~/.npm-global echo export PATH$HOME/.npm-global/bin:$PATH ~/.zshrc source ~/.zshrc npm install -g anthropic-ai/claude-codelatest配完之后npm config get prefix应该输出/Users/你的用户名/.npm-global以后所有全局包都装这里不再碰 Homebrew 或系统目录ENOTEMPTY 基本绝迹。4. 验证请求从 claude --version 到模型对话跑通配置写完不算完得验证两件事claude-code 本身装好了以及模型请求能通过 TaoToken 正常返回。分两步走。第一步验证安装claude --version # 期望输出类似1.0.xx (Claude Code)如果这条还报 ENOTEMPTY说明目录没清干净回到第 3 节重来。如果报command not found是 PATH 没配好检查npm config get prefix的 bin 目录有没有加进 PATH。第二步验证模型请求。最直接的方式是启动 claude-code 发一条消息claude # 进入交互界面后输入 用一句话说明你当前使用的模型如果配置正确会正常返回内容。如果返回 401说明 Key 有问题如果返回连接错误说明 Base URL 写错了。这两个错误的排查放到第 5 节。不想进交互界面的话可以用 curl 直接打 TaoToken 的接口验证 Key 和地址是否通curl https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoToken密钥 \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: ping}] }返回 JSON 里带content字段就说明通道通了。这一步能排除 claude-code 本身的干扰直接定位是 Key 问题还是工具问题。验证通过后建议做一次完整的编码任务测试比如让 claude-code 读一个文件并改一行cd ~/your-project claude 读取 package.json把 version 字段改成 1.0.1观察它是否能正常调用工具、读写文件。这一步过了说明安装、配置、通道三件事全部就绪。如果你更想先在网页端确认模型可用性可以到 https://taotoken.net/models 的对话入口发一条测试消息确认 Key 有额度、模型能响应再回到命令行配置。这样能把「Key 无效」和「配置写错」两类问题分开。实测下来最容易出问题的环节是ANTHROPIC_MODEL填了一个不存在的 Model ID。claude-code 不会在启动时报错而是在发请求时返回模型不存在。所以填之前一定去模型列表页核对别凭记忆写。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节把配置过程中最常撞的四个报错拆开讲每个都给定位方法和修复动作。401 UnauthorizedAPI Error: 401 {type:error,error:{type:authentication_error,message:invalid x-api-key}}原因只有三种Key 复制时带了空格或换行、Key 已失效、Key 填错了字段。检查~/.claude/settings.json里ANTHROPIC_AUTH_TOKEN的值前后不能有空格。如果确认没写错去 https://taotoken.net/api-keys 看这个 Key 是否还在、是否被禁用。重建一个再试。local proxy failed / connection refusedError: connect ECONNREFUSED 127.0.0.1:xxxx这是 Base URL 写成了本地地址或者你本地跑了个代理但没启动。检查ANTHROPIC_BASE_URL是不是https://taotoken.net/api别写成http://localhost:8080之类。如果你确实在用本地转发工具确认它开着但更推荐直接填 TaoToken 地址少一层依赖。reading choices / Cannot read properties of undefined (reading choices)TypeError: Cannot read properties of undefined (reading choices)这个错通常出现在用 OpenAI 兼容格式请求 Anthropic 接口或反过来。claude-code 走的是 Anthropic 的/v1/messages格式返回结构里是content不是choices。如果你在 Cline 里选了 OpenAI 协议却填了 Anthropic 的地址就会报这个。检查插件的 API 协议选项Anthropic 接口选 AnthropicOpenAI 接口选 OpenAI别混。OAuth 相关报错OAuth error: invalid_grantclaude-code 某些版本会尝试 OAuth 登录流程。如果你已经用 API Key 配置了还弹 OAuth说明配置没被读到。检查 settings.json 的路径对不对——用户级是~/.claude/settings.json不是~/.claude.json两个文件不一样。另外确认没有环境变量覆盖比如 shell 里 export 了ANTHROPIC_API_KEY它会优先于配置文件。排查清单速查报错首查项修复动作401Key 值有无空格重新复制或重建 Keylocal proxy failedBase URL 是否本地地址改为 https://taotoken.net/apireading choices协议选错Anthropic 接口选 Anthropic 协议OAuth invalid_grant配置文件路径确认是 ~/.claude/settings.jsonENOTEMPTY 复现目录权限/进程回第 3 节清理还有一个隐蔽的坑同时装了多个版本的 claude-codewhich claude指向的可能是旧版本。用which -a claude看所有路径把多余的删掉只留~/.npm-global/bin/claude或你 prefix 下的那个。6. 把 Key 通道固定下来长期编码场景的配置建议ENOTEMPTY 修一次就够了但 Key 通道的配置会跟着你很久。如果你打算长期用 claude-code 做编码建议把配置做成可复用、可迁移的形式而不是每次换机器重配一遍。第一把 settings.json 纳入 dotfiles 管理但 Key 不要硬编码。用环境变量引用{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: ${TAOTOKEN_API_KEY}, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }然后在~/.zshrc里export TAOTOKEN_API_KEYsk-...。这样配置文件可以进 GitKey 留在本地。第二项目级配置覆盖用户级。团队项目可以在.claude/settings.json里指定该项目专用的 Model ID比如代码审查用便宜模型、重构用强模型互不干扰。第三如果你同时用 Codex 和 claude-code把两者的 Base URL 都指向 TaoTokenKey 用同一个额度统一管理。Codex 的~/.codex/auth.json和 claude-code 的~/.claude/settings.json各配各的但 Key 值相同换 Key 时两处一起改。第四长期跑 Agent 任务的话关注一下 Coding Plan 的额度策略比按次调用更适合高频场景。入口在 https://taotoken.net/coding-plan 具体额度以页面为准。最后回到 ENOTEMPTY 本身。这个错的本质是文件系统状态和 npm 预期不一致跟 TaoToken、跟模型都没关系。修的时候别慌按「停进程 → 查权限 → 删目录 → 清缓存 → 重装」的顺序走九成情况一次解决。剩下那一成多半是 prefix 配错了或者有多个 Node 版本在打架用npm config get prefix和which -a node两个命令就能定位。配置通道的时候记住三件套Base URL 填https://taotoken.net/apiKey 从 api-keys 页面拿Model ID 去模型列表核对。三个都对上claude-code 就能稳定跑起来。