先说下背景。这篇是 OpenClaw 升级实战的续篇,上一篇聊的是基础部署,这篇记录的是把一台装了 npm 和 Yarn 混编环境的 Windows 机器升级到 OpenClaw 3.8 正式版的完整排障过程。本来我以为就是跑一条升级命令的事,结果从 PowerShell 执行策略卡住开始,一路碰到依赖树冲突、Python 版本不符、WSL 环境报警,前前后后折腾了一整晚才把服务拉起来。如果你也是那种“环境里既有 npm 又有 yarn、Node 装过不止一遍、还开过几个不同版本 Python 共存”的人,这篇排障记录应该能帮你少走不少弯路。
1. 升级前的环境体检:npm/Yarn 混装为什么必炸
1.1 先看清你手上到底是什么环境
升级不是上来就npm install -g一把梭。我做的第一件事是盘一下当前环境,把能查的全查了一遍:
node -v npm -v yarn -v openclaw --version npm ls -g --depth=0结果第一眼就发现问题了:这台机器上 npm 和 yarn 都装了,yarn -v能正常输出,说明 Yarn 是全局可用的。再往下看npm ls -g的列表,里面混着一些明显是用 Yarn 装到全局的包——这类包在 npm 的视角里是“不存在”的,但它们的可执行文件却躺在同一个 bin 目录里。这就是典型的 npm/Yarn 混装痕迹。
问题就出在这里:OpenClaw 3.8 的官方安装链路默认走 npm,而 Yarn 留下的node_modules结构、hoist 布局、以及缓存机制跟 npm 完全不互通。当你同时用两套包管理器操作全局包时,表面上一个包能跑,实际上是系统帮你把某个入口放到了 PATH 最前面,你根本不知道最终执行的是哪一份。
1.2 混装造成后果的底层逻辑
用个生活化的比喻:npm 和 Yarn 就像是两套独立的仓库系统,各记各的账。npm 记账的货物放在 A 仓库,Yarn 记账的货物放在 B 仓库,但两张账单共用一个出货口。升级时 npm 检查自己的“货物清单”(package-lock.json),发现 B 仓库里的“货”不在自己账本上,就认定版本缺失或者冲突,然后开始重新下载 B 里其实已经存在的那份依赖。
具体到 OpenClaw 升级场景,最常见的结果有几种:
- 老版本入口还挂在
node_modules/.bin或者全局 linkage 里,新版安装完成后openclaw命令调到的还是旧版,升级了等于没升; - 某个 peer 依赖被 Yarn 装成了旧版,npm 7+ 的严格解析机制直接报 ERESOLVE,拒绝继续安装;
- 两套缓存目录里都有部分 tarball,下载时互相干扰,明明网络没问题,却反复报 checksum 校验失败。
这就是为什么我反复强调:带着 Yarn 残留去升级 OpenClaw,运气好一次过,运气不好就是在给后边的每一步埋雷。所以这轮升级的第一步,明确就是把所有跟 OpenClaw 相关的 Yarn 入口清理干净,再谈装新版。具体怎么清,放到第四部分一起讲,因为前面还有几道坎挡着,不先绕过去,你连清理命令都跑不动。
2. 第一道坎:npm.ps1 无法加载,PowerShell 执行策略与双路径残留
2.1 报错现场
升级命令还没执行,先撞上了最烦人的一个报错:
npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。 有关详细信息,请参阅 about_Execution_Policies。这个报错我在很多装 Node 的机器上都见过,但不少人不知道它和升级 OpenClaw 有什么关系。关系很大:OpenClaw 3.8 的安装脚本、启动自检、周边小工具的调用大量依赖 PowerShell 环境,如果连 npm 都跑不了,后边 WSL 检查、模型桥接脚本大概率也跑不动。
有意思的是,同一个 npm 在 CMD 里能正常执行,在 PowerShell 里一敲就报错。原因不在 Node,在 PowerShell 的脚本执行策略。
2.2 报错背后的机制拆解
Windows 下 PowerShell 默认的ExecutionPolicy是Restricted,意思是禁止运行任何.ps1脚本。npm 本身提供两个入口:npm.cmd(批处理,CMD 和 PowerShell 都能直接跑)和npm.ps1(专门给 PowerShell 用的脚本)。在 PowerShell 里敲npm,解释器优先找npm.ps1;因为执行策略是 Restricted,这个脚本直接被打回。
这里有个很常见的误解:以为给当前用户设置成完全放开(Unrestricted)就完事。实践下来更稳妥的做法是RemoteSigned——本地创建的脚本允许运行,从网络下载的脚本必须带签名。对于 npm 这类本地安装的脚本完全够用,而且不会把安全边界拉得太低。
2.3 正确处理路径和第二个变体坑
在 PowerShell 里执行下面这条,只对当前用户生效:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser Get-ExecutionPolicy -List执行完用Get-ExecutionPolicy -List确认CurrentUser这一行是RemoteSigned,再敲npm -v验证。
但别急着高兴。如果你的机器跟我这台一样,之前装过不止一次 Node,还会遇到第二个变体报错——路径变成D:\Program Files\nodejs\npm.ps1或者C:\Users\Administrator\AppData\Roaming\npm下的脚本路径。这类报错的根源跟前一种完全不一样,是 PATH 里有多个 Node 安装目录残留。
解决办法是先检查解析到的到底是哪套安装:
where.exe node where.exe npm如果输出有多行,或者 node 和 npm 来自两个不同目录,说明旧 Node 路径还挂在 PATH 里。处理方式是把环境变量里旧的 Node 目录删掉,只留一份,然后重启 PowerShell 再验证。
这个细节花了我不少时间,因为当时node -v显示的是一份新版 Node,npm -v却调到另一个旧安装路径下的脚本,两边版本对不上。确认 PATH 干净之后,升级才敢真正进入依赖阶段。
3. 依赖树炸了:ERESOLVE 与 Node/Python 版本矩阵
3.1 你会在哪一步遇到 ERESOLVE
环境命令能跑之后,我直接尝试全局安装 OpenClaw 3.8,结果立刻收到一堆这种报错:
npm ERR! ERESOLVE overriding peer dependency npm ERR! While resolving: openclaw@3.8.0 npm ERR! Found: @some/package@2.1.0 npm ERR! Could not resolve dependency: npm ERR! peer @some/package@"^3.0.0" from openclaw@3.8.0npm 7 之后默认启用严格依赖解析。之前的 npm 6 遇到 peer 依赖冲突只是 warning,顶多装完跑不起来你不会太注意;npm 7+ 直接 ERROR 中断安装。OpenClaw 3.8 这类工具包在发布时会锁定一组 peer 依赖范围,本机若是残留着旧版本,就会卡在这里。
这时候很多人的第一反应是补一个--force或者--legacy-peer-deps硬闯过去。我的建议是:先看清楚冲突的到底是哪个包再决定。如果只是 OpenClaw 内部某个插件的 peer 要求和全局老包有出入,用--legacy-peer-deps装上,再回头逐个升级旧包,问题不大。如果冲突涉及 Node 运行时本身的能力(比如某些包要求node >= 18),那 force 只是饮鸩止渴,运行期会在奇奇怪怪的地方挂掉。
OpenClaw 3.8 对运行时的要求,官方发布说明里列得比较清楚。我在实操里的结论是:Node 版本最好在 18 LTS 及以上,npm 版本 9+ 更稳。如果你本机还停在一个很老的 Node 12 或 14,那别硬撑,先切版本再升级。用nvm或fnm切版本是最干净的做法,比去 Node 官网反复下载安装包好维护得多。
3.2 Python 3.8:容易被忽略的第二套运行时
OpenClaw 3.8 还有一个容易踩的隐性条件:它的一部分能力,尤其是本地模型桥接和若干 skill 的执行环境,依赖一套可用的 Python 运行时。热搜里出现的“modelscope 安装 qwen 3.8 / python 3.8”,说的就是这种场景——你想让 OpenClaw 关联到本地 qwen 模型,得先通过 ModelScope 把模型拉下来,而 ModelScope 的底层调用链对 Python 版本有硬性要求。
我当时的情况是:系统默认 Python 是 3.7,OpenClaw 3.8 的模型桥接脚本要求 Python 3.8 以上。装依赖时 pip 报了一堆Requires-Python >=3.8的错误,最后走了 conda 创建独立环境的路线:
conda create -n openclaw python=3.8 conda activate openclaw pip install modelscope实测下来,把 Python 版本拉起来之后,ModelScope 拉取 qwen 模型和 OpenClaw 关联调用的链路就通了。这里想提醒一句:OpenClaw 本身是 Node 工具,但它把模型层外置了,所以排查问题不要只盯着node_modules里的报错,也要检查 Python 侧。两边版本矩阵对不上,表观症状就是“装好了但模型加载不了,日志里看不出所以然”。
4. 干净升级的操作链:卸载残留、清缓存、换源、装 3.8
4.1 先把旧入口彻底卸掉
升级到 3.8 之前,我按第一部分的思路先把旧版 OpenClaw 卸干净。注意不能只用npm uninstall -g openclaw——因为混装环境里可能还有 Yarn 装的副本。推荐的清理链路是这样的:
# 1. npm 侧卸载 npm uninstall -g openclaw # 2. yarn 侧卸载(如果 yarn 里有副本) yarn global remove openclaw # 3. 找到残留入口 where.exe openclaw第三步很关键。where.exe openclaw会把 PATH 里所有匹配的可执行文件列出来。如果列出的路径不止一个,说明有硬链接残留,逐个删掉。Windows 上常见的残留位置是C:\Users\<用户名>\AppData\Roaming\npm,也就是 npm 的全局 bin 目录,老版本的入口文件可能躺在那里没被卸载脚本清掉。
4.2 清缓存和 lock 文件
卸载之后,我顺手把缓存和 lock 一起清了一遍。这一步在“混装升级”场景里特别重要,因为 npm 和 Yarn 各自的 lock 文件会互相干扰:
npm cache verify然后在项目目录里:
rm -Recurse -Force node_modules rm package-lock.json rm yarn.lock为什么 lock 文件要删?Yarn 的yarn.lock和 npm 的package-lock.json记录的是两套依赖树快照。升级主工具版本时,旧 lock 里残留的解析结果可能和 3.8 的依赖要求冲突。删掉之后让 npm 重新解析一遍,反而最稳。
这里多说一句npm cache verify的作用:它不是简单地清空缓存,而是校验缓存数据的完整性,顺便清理无效损坏的 tarball。在混装环境里,包可能分别从不同源、不同工具下载过,缓存目录里同一版本存在多份哈希不同的文件,verify 会帮你把不匹配的踢掉,避免后续安装时出现“明明下载了却说校验失败”的诡异问题。
4.3 换源:不是可选项,是省命选项
OpenClaw 3.8 的依赖链不小,直接走默认源在部分地区下载会非常慢,甚至超时。国内实操基本上都会切 npm 镜像,我用的是 npmmirror(也就是大家常说的淘宝源):
npm config get registry npm config set registry https://registry.npmmirror.com这里有一个我踩过的点:换完源后建议再做一次npm cache verify。因为混装环境里缓存下载的 tarball 可能来自不同源,源切换后校验值对不上会报内部错误。先把旧缓存清掉再拉新包,整个过程会顺很多。
另外提一句镜像源的更新频率:npmmirror 这类镜像对热门包的同步基本是分钟级,OpenClaw 3.8 发布后很快就能拉到,不放心的话可以先npm view openclaw version确认一下镜像上有没有你要的版本,避免装到一个过期缓存。
4.4 正式安装 3.8
最后执行安装。虽然官方提供了升级命令,但按前面的清理步骤走完后,我选择直接干净安装固定版本:
npm install -g openclaw@3.8.0这里不推荐用@latest而不加确认,因为你不知道此刻 latest 指向的是 3.8 还是 3.9。写明确版本号,升级行为完全可控。装完第一件事不是急着跑,而是验证:
openclaw --version版本号输出正确,再往下进入功能验证。这一步也想提醒一下:如果你升级完发现openclaw还是旧版本号,第一反应不要怀疑安装失败,先执行where.exe openclaw检查 PATH 是不是解析到了旧目录。这是混装环境升级后最容易出现的假象,我见过不止一次。
5. 升级后的验证清单与残坑:WSL、缺失可选依赖和本地模型
5.1 WSL 2 环境未就绪的报错
装完 3.8,第一次跑自检,弹出来的不是程序日志,而是这样一条提示:
无法安全验证 SL2 环境。请在 PowerShell 中运行 wsl --status 解决报告的问题。这里的 SL2 指的就是 WSL 2。OpenClaw 3.8 的某些组件,比如沙箱执行、容器化 skill 环境,启动时会检查 WSL 2 是否可用。如果以前没配过 WSL,或者默认版本还是 1,就会卡在这个检查上。
处理方式不复杂:
wsl --status wsl --set-default-version 2第一条命令先看清楚当前状态,如果提示没有已安装的发行版,还要先wsl --list --online看可用的发行版并装一个。这里不用纠结发行版是 Ubuntu 还是 Debian,OpenClaw 要的是“WSL 2 的内核环境存在”,不是特定某个发行版。
5.2 missing optional dependency:不用慌
安装日志里还有一条容易被误判为“装失败了”的警告:
missing optional dependency @openai/codex-win32-x64. reinstall codex: npm install这个看着吓人,其实说的是某个特定平台的预编译二进制不存在。Windows x64 上某些包没有提供预编译产物,npm 会把它标记为optional缺失,然后在需要的时候走源码编译或者直接跳过。
我的做法是先确认功能是否受影响:OpenClaw 3.8 自检能通过、skill 列表能正常列出、模型桥接能联通,就说明这个可选依赖不影响当前主要使用路径。如果后续真的用到对应的 codex 相关能力,再去项目目录执行一次补装即可,不需要在升级阶段跟它死磕。
5.3 把本地模型关联起来测试
最后一步是验证 3.8 的完整功能,重点是把本地模型接进来测一遍。我用的是 qwen2.5-3b,ModelScope 下载完成后,在 OpenClaw 配置里把模型端点指到本地服务。
如果你之前 Python 用的不是 conda 环境,这块很容易在版本上翻车。我的建议是:OpenClaw 3.8 的模型桥接脚本、ModelScope 的依赖、以及模型推理进程,尽量跑在同一套 Python 环境里,避免系统 Python 和 conda base 环境互相覆盖。跑通一次对话,确认 OpenClaw 能正确调用本地模型,这次升级才算真的落地。
说实话,这次从 npm/Yarn 混装环境升到 3.8 正式版,最大的体会就一句话:环境越乱,越要先清理再升级,而不是靠--force硬闯。PowerShell 执行策略、PATH 双目录、Python 版本、WSL 状态这些看起来和“升级”无关的检查,反而决定了升级能不能顺利完成。从那次之后,我把这几项固化成自己的升级前 checklist,每次碰大版本升级先过一遍,后面踩的坑确实少了很多。