工具大全
踩坑实录作者:Coocon2026年9月29日14 次阅读约 11 分钟阅读

Claude Code 安装失败实测:npm EACCES、镜像卡 600 秒、Node 20 静默装旧版、install.sh 返回地区拦截页、原生安装器顺手卸掉 npm 版——15 条报错原文与解法

搜「claude code 安装」的人,大多数不缺教程——缺的是装到一半报错时,这句报错到底是什么意思。安装步骤本站已经有了(Claude Code 快速上手),这篇不重复,只做一件事:把安装会失败的地方在本机一个个真实复现,逐字记下报错原文、触发条件、耗时和退出码,再给出解法。

先说最意外的三条:

  1. Node 20 装 Claude Code 不会报错,而是静默装到 2.1.197。engines 从 2.1.198 起要求 >=22,npm 会自动挑一个旧的、满足条件的版本,没有任何警告。
  2. 在国内直连 curl -fsSL https://claude.ai/install.sh 时,curl 退出码是 0,下载下来的却是 447,830 字节的「App unavailable in region」HTML 页面。| bash 之后只会看到一句 syntax error near unexpected token '<'。
  3. 官方原生安装器会执行 npm uninstall -g @anthropic-ai/claude-code,把你已有的 npm 版删掉,终端里一个字都不提。本次实测就这样真的删掉了本机的全局安装——下面「踩坑」一节有完整经过。

假 npm 记录到原生安装器的调用:npm uninstall -g @anthropic-ai/claude-code

问题背景

Claude Code 现在有两条官方安装路径:

  • npm:npm install -g @anthropic-ai/claude-code。现在的包只是一个「壳」:真正的程序是平台对应的 optionalDependency(例如 @anthropic-ai/claude-code-darwin-arm64,tarball 98,952,459 字节)。postinstall 脚本 install.cjs 会把这个原生二进制硬链接到 bin/claude.exe。claude 命令本身已经不是 JS 了,而是一个 Mach-O 可执行文件(2.1.284 为 226,563,088 字节)。
  • 原生安装器:curl -fsSL https://claude.ai/install.sh | bash。脚本从 downloads.claude.ai 下载二进制、校验 sha256,然后执行 claude install,最终装到 ~/.local/bin/claude。

这两条路径各有各的失败面,而国内网络环境会让其中好几个失败面的报错看起来和真正的原因毫无关系。

问题分析

把「claude code 安装失败」拆开,能出问题的环节有这些:

环节 可能出的事 本文对应
写入全局目录 prefix 没有写权限 表中 #1
npm cache cache 目录不可写 #2
registry 连不上、DNS 解析不了、镜像慢 #3 #4 #6
代理 npmrc 与环境变量冲突 #5
Node 版本 engines 门禁 #7 #8
原生安装器 地区拦截、下载服务连不上、覆盖 npm 版 #9 #10 #12
装完之后 PATH、postinstall 没跑、用错启动方式 #11 #13 #14 #15

还有一个前提容易被忽略:npm install -g 读不到项目目录里的 .npmrc。实测在仓库根目录(其 .npmrc 写着 npmmirror),隔离 HOME 之后:

$ npm config get registry        → https://registry.npmmirror.com/
$ npm config get registry -g     → https://registry.npmjs.org/

也就是说,全局安装实际生效的只有 ~/.npmrc、全局 npmrc 和命令行参数。排查 registry / 代理问题时,一定要用 npm config get xxx -g 看。

技术方案与选型

目标是「真实复现 + 不破坏本机」,方案如下:

  • 所有安装都隔离:--prefix、--cache、--logs-dir 全部指向 /tmp/cc-install-0929/ 下的子目录,不写 ~/.npm 和 /opt/homebrew(原生安装器那一次例外,见「踩坑」)。
  • 失败面用可控的坏值触发:registry 指向 127.0.0.1:1 和 .invalid 域名,代理指向 127.0.0.1:1/:2,cache 用 0555 目录,权限用 /usr/local。
  • 低版本 Node 用便携版:本机的 22 / 24 / 25 都满足 >=22,于是在 /tmp 下解压了 Node v20.19.5(npm 10.8.2),不用 nvm,也不改系统。
  • 网络对照:镜像和官方源分别用独立 cache,否则第二次会命中相同 integrity 的缓存,测不出下载时间。

排除项:

  • 不测 Windows / Linux:只有一台 macOS,写不出没测过的报错原文。
  • 不测 sudo npm install -g:会写系统目录,而且这是网上最常见的错误建议,不值得为它破坏本机。
  • 不测 pnpm / yarn / bun:报错原文里提到了「some pnpm configs」,但本次没有复现,不下结论。
  • 不调用 API:安装问题与模型无关,全程 0 次 API 调用,花费 ¥0。

实测过程

  • 环境:macOS 26.3.1,Apple Silicon;Node v25.9.0,npm 11.11.0;北京直连,出口 AS4847,没有系统代理,也没有 TUN。
  • 本机原有 Claude Code 2.1.280(Homebrew 下的 npm 全局安装)。npm 上的 dist-tags 为 latest 2.1.284、stable 2.1.277,所以不钉版本时装到的是 2.1.284。
  • 每一组都记录了逐字命令、stdout+stderr、墙钟秒数和 exit code;带颜色的输出保留为 .ansi,截图用它渲染,没有手写的输出。
  • 时间:2026-09-29 10:02–10:37。

实践效果:15 条报错原文对照表

「解法已实测」一列标 ✅ 的,是本次在本机验证过的;标「未实测」的是依据报错文案或文档给出的建议。

# 报错原文(节选) 触发条件 墙钟 exit 解法 解法已实测
1 npm error code EACCES … Error: EACCES: permission denied, mkdir '/usr/local/lib' 全局 prefix 没有写权限 0.12s 243 不要 sudo。把 prefix 换到用户可写的目录(npm config set prefix ~/.npm-global,再把 ~/.npm-global/bin 加进 PATH),或者用 Homebrew / nvm 装的 Node ✅(所有 --prefix /tmp/... 的安装都成功)
2 Your cache folder contains root-owned files, due to a bug in previous versions of npm … sudo chown -R 501:20 "…" cache 目录不可写——本次属主就是自己,只是权限 0555 1.45s 1 先 ls -ld "$(npm config get cache)",看清是属主问题还是权限位问题;只有确实是 root 属主时才 chown 未实测(只验证了报错)
3 FetchError: request to http://127.0.0.1:1/… failed, reason: connect ECONNREFUSED 127.0.0.1:1 registry 端口不通 3.16s(缩短重试参数)/ 70.15s(默认参数) 1 npm config get registry -g 找出是谁配的,改掉 ✅
4 network request to https://nonexistent-cc-0929.invalid/… failed, reason: getaddrinfo ENOTFOUND registry 域名解析不了 3.86s 1 同上 ✅
5 request to https://registry.npmjs.org/… failed, reason: connect ECONNREFUSED 127.0.0.1:2 npmrc 里残留的 proxy=/https-proxy= 压过了环境变量 HTTPS_PROXY 0.13s 1 npm config get proxy -g 和 npm config get https-proxy -g 一起查,删掉残留项 ✅(换成空 userconfig 后恢复只读 env)
6 无报错,只是卡住:147.22s 装完 / 超过 600s 被我 kill 本机经 npmmirror 下载平台包 147s / >600s 0 / kill 加 --registry https://registry.npmjs.org 对照一次 ✅ 本机官方源 10.74s / 12.20s(各 2 个样本)
7 没有报错:added 2 packages in 21s,然后 claude --version → 2.1.197 Node <22 且不钉版本号 21s 0 升级到 Node ≥22;装完先看 claude --version ✅(Node 25 下装到 2.1.284)
8 npm warn EBADENGINE Unsupported engine / 加 --engine-strict 后变成 npm error code EBADENGINE Node <22 钉 @2.1.284 5.51s / 0.17s 0 / 1 同上 ✅
9 bash: line 1: syntax error near unexpected token '<'(HTML 的 <title>App unavailable in region</title>) 国内直连 claude.ai/install.sh 6.27s / 3.00s(两次) curl 0 先落盘 -o install.sh 再 head -1 看一眼;在国内改走 npm 路线,或者通过代理 ✅(走代理后拿到 9,704 字节的真脚本)
10 curl: (28) Failed to connect to downloads.claude.ai port 443 after 75595 ms 国内直连下载服务 75.63s 28 走代理 ✅(51.74s 装好)
11 Native installation exists but ~/.local/bin is not in your PATH 原生安装完成后 51.74s 0 按提示把 ~/.local/bin 加进 PATH(安装器不会自动改 ~/.zshrc) ✅
12 没有任何输出,后台执行了 npm uninstall -g @anthropic-ai/claude-code 之前用 npm 全局装过,再跑原生安装器 28.76s(安装器整体) 0 想保留 npm 版就别跑原生安装器;跑了的话,用 which -a claude 确认现在用的是哪一份 ✅(假 npm + strings 双证据,见下)
13 zsh:1: command not found: claude PATH 里没有 $(npm prefix -g)/bin 或 ~/.local/bin 0.11s 127 把对应的 bin 目录加进 PATH ✅
14 Error: claude native binary not installed. … node node_modules/@anthropic-ai/claude-code/install.cjs --ignore-scripts 安装,postinstall 没跑 0.84s npm 0,claude 1 去掉 --ignore-scripts 重装,或者手动 node "$(npm root -g)/@anthropic-ai/claude-code/install.cjs" 未实测
15 TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".exe" 按旧教程 node …/bin/claude --version — 1 直接执行 …/bin/claude --version ✅

下面挑几条展开。

#1 #2:权限类报错,第二条的诊断是错的

--prefix /usr/local 是最典型的 EACCES:0.12 秒就失败,exit 243,因为 mkdir '/usr/local/lib' 这一步就被拒了,所以没有留下半成品(/usr/local 实测与基线一致)。

npm install -g --prefix /usr/local:EACCES,exit 243

cache 那条更值得注意。我给 cache 目录设了 0555,属主就是当前用户 duoduo,npm 的报错却是「你的 cache 目录里有 root 拥有的文件,这是旧版 npm 的 bug」,并建议 sudo chown -R 501:20。照做修不好,因为问题根本不在属主。先 ls -ld 看清楚再动手。

cache 目录只是 0555,npm 却报 root-owned 并建议 sudo chown

#3 #4 #5:连不上时,npm 默认会等 70 秒

npm 默认 fetch-retries=2,退避 10s → 60s。registry 端口被拒(ECONNREFUSED)时,默认参数下 3 次尝试一共 70.15 秒才报错;把重试参数调短后是 3.16 秒。DNS 解析失败(ENOTFOUND)同样是 3 次尝试。看起来像「卡住了」的安装,不一定真卡住,可能只是在重试。

代理那条实测了 5 组:

环境变量 隔离 npmrc npm 实际连的
HTTPS_PROXY=:1 空 :1
HTTPS_PROXY=:1 https-proxy=:2 :2
HTTPS_PROXY=:1 proxy=:2 :2
无 proxy=:2 :2(proxy= 对 https registry 同样生效)
小写 https_proxy=:1 空 :1

结论:npmrc 里的代理配置优先于环境变量,哪怕写的只是 proxy=。报错文案里的 URL 是 registry,端口却是代理的端口,全文也没有点明这是代理的问题——很容易以为是 registry 挂了。另外,npm 走不走代理和 Node 内置 fetch 是两回事,后者不认 HTTPS_PROXY,见这篇。

#6:镜像 vs 官方源(只有 2 个样本)

组 registry 墙钟 exit
镜像第 1 次 npmmirror(经 ~/.npmrc) 147.22s 0
镜像第 2 次 npmmirror >600s,被 kill —
官方源第 1 次 registry.npmjs.org 直连 10.74s 0
官方源第 2 次 registry.npmjs.org 直连 12.20s 0

npm 调试日志显示,镜像慢在 cdn.npmmirror.com 上那个 99MB 的平台包:139,231ms;官方源同一个包是 6,881ms / 7,619ms。用 curl 单独拉镜像的同一个文件,125.7 秒后以 exit 35(SSL 连接错误)失败;官方源 7.66 秒,12.9 MB/s。

适用范围要说清楚:这是 2026-09-29 上午、北京、AS4847 出口、每组 2 个样本的结果,不能推广成「镜像一定比官方源慢」。但它说明一件事:「国内就该用镜像」不是无条件成立的,装不动时拿 --registry https://registry.npmjs.org 对照一次,成本只要十几秒。另外,被 kill 的那次在 prefix 里留下了只有 lib/ 的半成品目录。

#7 #8:Node 20 不会报错,而是装旧版

这一条是本次最隐蔽的。查 npm 上每个版本的 engines:2.1.197 及以前是 >=18.0.0,从 2.1.198 起是 >=22.0.0。在 Node v20.19.5 下:

  • 不钉版本:added 2 packages in 21s,exit 0,装到的是 2.1.197,没有任何警告;
  • 不钉版本 + --engine-strict:一样装到 2.1.197,照样没警告;
  • 钉 @2.1.284:只有 npm warn EBADENGINE,exit 0,装出来的二进制照样能跑(它是原生程序,不依赖 Node);
  • 钉 @2.1.284 + --engine-strict:npm error code EBADENGINE,exit 1,0.17 秒,并留下一个空的 lib/。

Node v20.19.5:不钉版本静默装到 2.1.197;钉 @2.1.284 只有 EBADENGINE 警告

所以如果你在 Node 18/20 上装完发现「文档里的新功能怎么没有」,先看一眼 claude --version。

#9 #10 #11 #12:原生安装器的四个坑

**地区拦截页被当成脚本。**国内直连时 claude.ai/install.sh 先 302 跳到 claude.com/app-unavailable-in-region,再返回 200 text/html。curl -fsSL 的 -f 只对 HTTP 错误码生效,所以 curl 退出码是 0。10:19 和 10:37 两次复现结果一致,都是 447,830 字节。

北京直连 claude.ai/install.sh:curl exit 0,拿到的是地区拦截页 HTML

**下载服务连不上。**用代理拿到真脚本后,在直连下运行:脚本在第一步请求 downloads.claude.ai/claude-code-releases/latest 时,curl 75,595 ms 后报 (28)。脚本里其实写了友好提示(not available in your region),但因为 set -e 加命令替换,脚本直接以 curl 的 28 退出,友好提示没有机会显示。

**走代理能装好,但 PATH 要自己加。**51.74 秒装好 2.1.284,产物是 ~/.local/bin/claude → ~/.local/share/claude/versions/2.1.284(约 216MB)。安装器提示 ~/.local/bin is not in your PATH,给出了 echo … >> ~/.zshrc,但不会替你执行。

**它会卸掉你的 npm 版。**原生二进制的 install 子命令会检查是否存在 npm 全局安装,如果有,就执行 npm uninstall -g @anthropic-ai/claude-code。我用两种互不依赖的方法确认了这一点:

  1. 假 npm:在 PATH 最前面放一个只记录参数、然后 exit 0 的 npm,同时设置 npm_config_prefix 指向隔离目录做双保险,再执行 claude install。记录下来的调用只有一条:[uninstall] [-g] [@anthropic-ai/claude-code]。
  2. strings:在 2.1.284 二进制的偏移 189061680 处找到 qe("npm",["uninstall","-g",e],{cwd:process.cwd(),…}),成功后调用 t(\Removed global npm installation of ${e}`)`——这是写日志,不是终端输出,所以屏幕上看不到。

安装器的终端输出从头到尾只有 Checking installation status… / Installing… / ✔ Claude Code successfully installed!。从产品角度这大概是有意的「迁移」,但如果你同时依赖 npm 版(比如脚本里写死了 /opt/homebrew/bin/claude),它就会悄无声息地失效。

#14 #15:装完了却跑不起来

--ignore-scripts 安装:npm exit 0,看上去一切正常(安装加运行整组 0.84 秒),但 bin/claude.exe 只有 500 字节,是个占位文件,一运行就报 Error: claude native binary not installed.,exit 1。报错文案本身写得很清楚,给出了手动跑 postinstall 的命令。

--ignore-scripts:npm exit 0,但 bin/claude.exe 只是 500 字节占位

老教程里的 node $(npm root -g)/@anthropic-ai/claude-code/…/claude 这种写法已经不能用了:node …/bin/claude --version 报 ERR_UNKNOWN_FILE_EXTENSION ".exe",因为那是 Mach-O 二进制,直接执行即可。

装好、能跑之后,如果登录时报 Invalid API key / Not logged in,那是认证问题,不是安装问题,见 Claude Code 认证报错实测。

未复现 / 不适用

  • --omit=optional 未复现:报错文案说它会导致缺少二进制,但在 npm 11.11.0 的全局安装里,平台包照样装上了,claude --version 正常。
  • 「换个 Node 版本就跑不起来」不适用:产物是原生二进制,otool -L 只链接了系统库;Node 20 / 22 / 25 下都能运行,cli-wrapper.cjs 也是。所谓 ABI 问题在当前版本已经不存在。
  • 同版本重装:npm 显示的是 changed 2 packages(4.80s,再来一次 0.87s),而不是 up to date。

踩坑

**只隔离 HOME,挡不住全局 npm 的写入。**跑原生安装器时,我把 HOME 指向了 /tmp,以为这样就隔离了。结果安装器执行的 npm uninstall -g 用的是 npm 内置配置里的全局 prefix(/opt/homebrew),这个 prefix 和 HOME 无关——本机真实的 2.1.280 全局安装就这样被删掉了,claude 直接变成 command not found。之后用 npm install -g @anthropic-ai/claude-code@2.1.280 --registry https://registry.npmjs.org 恢复,约 3 秒。所以第 12 条的证据才会有三份:一份意外撞出来的 npm 调试日志(argv "uninstall" "--global" "@anthropic-ai/claude-code"),外加事后用假 npm 和 strings 做的安全复现。跑别人的安装器前,要么设 npm_config_prefix 指向隔离目录,要么把 npm 移出 PATH。

curl -f 挡不住地区拦截页。-f 只看 HTTP 状态码,302 跳转后的 200 HTML 它照单全收。curl … | bash 前先落盘看一眼。

**PATH 里的空格。**复现第 12 条时,第一次的 env PATH=$T/shim:$PATH … 因为 PATH 里有 VMware Fusion.app 这样带空格的目录而解析失败,exit 127——好在安装器根本没有执行。拼 PATH 时要加引号。

**把 --ignore-scripts 当成标题传给 npm run。**用 npm run term-shot … "--ignore-scripts:…" 出图时,npm 把以 -- 开头的标题当成了自己的参数吞掉了,两张图的标题都成了默认值。要写成 npm run term-shot -- …。

相关文章

这类实测,每周六汇总一封

订阅码农早餐:每天 8:00 一封 AI 编程早报,每周六另附本周 Claude Code / Codex / 本地模型的实测和踩坑汇总。

相关文章

DeepSeek harness 实测:同一个模型换三种外壳——Claude Code 15/15、Codex CLI 15/15、裸 API 0/15 还谎报 5 次完成

DeepSeek harness 实测:同一个模型换三种外壳——Claude Code 15/15、Codex CLI 15/15、裸 API 0/15 还谎报 5 次完成

同一个 deepseek-v4-pro,三种 harness,读 / 写 / 改 / 跑命令 / 多步五个任务各 3 轮,副作用一律落盘核验。Claude Code 走 DeepSeek 的 Anthropic 端点:15/15,中位 4.17 秒,每轮 ¥0.159。Codex CLI 0.157.1 走 Responses 端点:15/15,中位 15.52 秒,每轮 ¥0.022——只有前者的 1/7。裸 chat/completions:0/15,其中 5 轮回复 DONE / EDITED,磁盘上什么都没有。差异全在 harness 不在模型:DeepSeek 的 Anthropic 端点按 metadata.user_id 分区缓存,Claude Code 每次 claude -p 都冷启动、约 15K token 全价;Codex 根本没有文件工具,读写改全走 shell;注入 500 时 Claude Code 重试 10 次约 175 秒、Codex 30 次约 25 秒放弃,429 时 Codex 不重试;120KB 输出时 Claude Code 只给模型看头部 2KB,Codex 保留头尾。另:Codex 0.157.1 已移除 wire_api = "chat",DeepSeek 必须走 responses。

claude-codedeepseek+6
hands-on2026年9月28日12 min
62
Claude Code「bash denied by auto mode」怎么办:被拦原因、could not evaluate 与 unavailable for this model 逐条实测

Claude Code「bash denied by auto mode」怎么办:被拦原因、could not evaluate 与 unavailable for this model 逐条实测

auto 模式下 Bash 被拦,常见的有三种提示:denied by auto mode、Auto mode could not evaluate this action、auto mode unavailable for this model。本文在 Claude Code 2.1.280 上跑了 40 多次真实会话。结论:denied 是分类器判定你的命令越权,最常见的理由是 [Code from External],也就是执行了你没有点名的外部代码,重试没用,要么在 prompt 里点名来源,要么在用户级 settings 的 autoMode.environment 里声明信任;could not evaluate 是分类器没给出可解析的结论;unavailable for this model 是模型比 claude-opus-4-6 旧,claude -p 下会被静默降级、只在 debug 日志里留一行 WARN。另外,2.1.280 的判定已经改到服务端,随主请求一起返回。经过「只允许 Claude Code 客户端」的中转网关时,本地兜底的分类器请求会被 503 拒绝,这就是「temporarily unavailable (server error)」的一个固定成因。

claude-codeauto-mode+4
pitfalls2026年9月27日9 min
72
Claude Code 报错 Invalid API key · Fix external API key 怎么排查:Not logged in、Credit balance is too low、API Error 401/429/529 原文与重试实测

Claude Code 报错 Invalid API key · Fix external API key 怎么排查:Not logged in、Credit balance is too low、API Error 401/429/529 原文与重试实测

用本地 stub 模拟 Messages API,在 Claude Code 2.1.280 上跑了 28 组 case、61 次 claude -p。结论:401 会重试 10 次、约 3 分钟后才报 Invalid API key · Fix external API key;key 含中文或中间换行则在本地就被拦,0 个请求、0.28 秒。所有报错都打在 stdout,stderr 为 0 字节,exit 1;JSON 里 subtype 仍是 success。CLAUDE_CODE_MAX_RETRIES=0 让 401 在 0.28 秒内失败。KEY 和 TOKEN 同时设置时两个 header 都会发。

claude-codeclaude-code-lab+4
pitfalls2026年9月27日10 min
72
Claude Code 报错 Command timed out after 2m 0s 怎么解决:两条超时路径、BASH_DEFAULT_TIMEOUT_MS 与 run_in_background 实测

Claude Code 报错 Command timed out after 2m 0s 怎么解决:两条超时路径、BASH_DEFAULT_TIMEOUT_MS 与 run_in_background 实测

Claude Code 的 Bash 工具默认 120 秒超时。本文在 2.1.280 上跑了 19 次真实会话,结论是:超时分两条路径,只有首词是 sleep 的命令才会被杀,并报 Exit code 143 / Command timed out after 2m 0s;其它命令到点会被转到后台,在 claude -p 收尾 5 秒后被 kill。无论哪条路径,claude 进程都 exit 0、stderr 为 0 字节,JSON 顶层 is_error=false。BASH_DEFAULT_TIMEOUT_MS=8000 实测 8.17 秒被杀;设成 0 或 abc 会静默回落 120 秒;显式 timeout 超过 BASH_MAX_TIMEOUT_MS 会被静默夹到 15 秒。

claude-codeclaude-code-lab+4
pitfalls2026年9月26日8 min
79