在PowerShell里敲下 npm install 回车,等了半天,屏幕上却没有按预期开始刷依赖列表,而是弹出一段红字,里面同时出现了 D:\openclaw\node_modules\npm\bin\npm-cli.js 和 CategoryInfo : NotSpecified: (npm error co... 两行看起来完全不像普通报错的东西。我第一次遇到的时候也懵了:npm 不是在运行吗?怎么还报一个找不到类别的错误?
后来才搞清楚,这个问题根本不是 npm 本体坏了,而是 Windows 的 PowerShell 压根没允许 npm 的脚本启动。对于准备在 Windows 上部署 OpenClaw 的朋友来说,这基本是绕不过去的第一个坎。OpenClaw 这类智能体项目,不管你想接微信、飞书还是钉钉,第一步大概率都是 npm install,所以把这条链路彻底弄明白,后面能省掉很多折腾时间。这篇文章就用我实际踩坑的视角,把 Windows 上 npm 启动失败、node_modules 异常、OpenClaw 启动后连不上模型等问题完整捋一遍,每个问题都会给到可以直接抄的解决方案。
1. 从报错现场出发:npm-cli.js、CategoryInfo 和 PowerShell 到底拦住了什么
1.1 报错信息在说什么
先拆第一段报错,路径是 D:\openclaw\node_modules\npm\bin\npm-cli.js。很多人看到这个路径会以为 npm 找不到自己了,实际上它是在告诉你:npm 其实是一个 Node.js 脚本,真正的入口就是这个 npm-cli.js。在 Windows 上,npm 安装时会生成几个启动器,比如 npm.cmd、npm.ps1,它们的作用就是用 Node 去执行这个 npm-cli.js。所以当你在 PowerShell 里输入 npm 时,PowerShell 其实是在尝试调用 npm.ps1 这个脚本,再由它去拉起 Node 和 npm-cli.js。
再拆第二段,CategoryInfo : NotSpecified: (npm error co...。这个格式不是 npm 输出的,而是 PowerShell 在把原生程序输出包装成错误记录时统一加的壳。CategoryInfo 是 PowerShell 错误记录的一个属性,NotSpecified 表示它无法把这条错误归类到某个具体的 .NET 异常类型里。也就是说,这一行只是“外壳”,真正的错误原因在后面的 npm error co... 里。如果你只盯着这个 CategoryInfo 看,会浪费很多时间。真正要关注的,是它前面那条更经典的报错:“无法加载文件 ...\npm.ps1,因为在此系统上禁止运行脚本”。
也就是说,这条报错链的完整逻辑是:PowerShell 想执行 npm.ps1,但被 Windows 的执行策略拦住了,于是它没能正常启动 npm-cli.js,所有后续输出都被 PowerShell 包成了一个 CategoryInfo : NotSpecified 的错误记录。问题根源在 PowerShell 的执行策略,而不是 npm 被删了或者 Node.js 坏了。
1.2 为什么 PowerShell 会禁止运行脚本
Windows 的 PowerShell 有一套执行策略(Execution Policy),它控制着 .ps1 脚本能不能运行。默认策略在不同系统上不完全一样,但很多 Windows 机器默认是 Restricted,也就是禁止运行任何 .ps1 脚本。npm 在 Windows 上偏偏主要依赖 npm.ps1 作为启动器,于是整个 npm 就被“一刀切”拦住了。
你可以把执行策略理解成小区门口的保安。保安的职责不是判断访客是好是坏,而是看这个访客有没有“出入证”。npm.ps1 是一个本地生成的脚本文件,没有任何签名,默认规则下属于“没有许可证的陌生人”,所以直接被拒绝进入。问题在于,这个“门禁规则”平时开发时几乎不会用到,一旦项目需要跑 npm 命令,就被卡住了。
PowerShell 的执行策略其实分多个作用域,可以用 Get-ExecutionPolicy -List 查看。常见策略值和作用如下:
| 策略值 | 含义 | 适用场景 |
|---|---|---|
| Restricted | 禁止运行任何 .ps1 脚本 | Windows 默认策略,安全性最高,但不适合日 |
