☰
OpenClaw 报错 Unable to resolve bundled plugin speech-core/runtime-api.js:从定位到修复的完整排查记录
2026/10/3 6:49:59 网站建设 项目流程

1. 先别急着删库:这个报错到底卡在哪一环

OpenClaw 启动时抛出Unable to resolve bundled plugin speech-core/runtime-api.js,本质是插件解析链路在“内置插件运行时入口”这一步断了。OpenClaw 的插件分两类:一类是随主包分发的 bundled plugin,比如 speech-core、discord-core 这些;另一类是用户自己放进 extensions 目录的外部插件。bundled plugin 不需要你单独npm install,它的runtime-api.js应该躺在安装目录的dist/extensions/speech-core/下面。启动时 OpenClaw 会按注册表逐个 resolve 这些入口文件,任何一个路径对不上,就会把整条链路标记为失败。

这个报错最迷惑人的地方在于:你明明没开语音功能,它却偏偏报 speech-core。原因在于 OpenClaw 的插件加载是“全量预解析”策略——网关启动阶段会把所有 bundled plugin 的 public surface 先扫一遍,注册到运行时上下文里,而不是等你调用语音接口才加载。所以只要 speech-core 的文件缺失或路径错位,哪怕你只用文本 Agent,网关也会在初始化阶段直接失败,表现为Agent failed before reply。

适合谁看:正在用 OpenClaw 搭本地 Agent 网关、跑 Discord/Telegram 机器人、或者刚升级完版本发现启动不了的同学。我试过在 Windows 和 Linux 两种环境下复现,触发条件高度一致,下面把定位命令和修复配置都拆开讲。

先建立一个判断顺序,避免上来就重装:

现象大概率原因优先动作
openclaw --version正常,仅插件报错插件目录文件缺失/路径错配检查 dist/extensions
openclaw --version也报错主包安装损坏重装主包
升级后首次启动报错新旧版本文件混用清理后重装
报错里带Cannot find module ...openclaw.mjs核心入口丢失彻底卸载重装

这张表是我踩过几次坑之后总结的,核心逻辑是:先确认 CLI 本身活着,再谈插件。如果连openclaw --version都跑不出来,那问题根本不在 speech-core,而是主包安装层已经烂了,这时候去改插件配置纯属浪费时间。

还有一个容易忽略的点:OpenClaw 的插件解析对路径大小写和斜杠方向敏感。Windows 下如果用某些解压工具手动挪过node_modules,可能出现Speech-Core和speech-core并存的情况,resolve 时按注册表里的小写名去找,自然找不到。这类问题用openclaw doctor不一定能自动修,得手动核对目录名。

所以第一步不是急着敲修复命令,而是把“报错发生在哪一层”确认清楚。下一节先讲怎么用 TaoToken 把模型侧配置理顺,因为很多同学在修插件的同时,模型接入的 Base URL 和 Key 也是乱的,两边一起排查效率更高。

2. 用 TaoToken 把模型接入层先理顺

插件报错和模型接入看起来是两件事,但实际排查时经常纠缠在一起。OpenClaw 的 Agent 会话失败,日志里既有Unable to resolve bundled plugin,也可能夹着模型请求 401 或local proxy failed。如果你一边修插件一边还在怀疑是不是 Key 配错了,排查会非常痛苦。我的做法是:先把模型接入层用 TaoToken 固定下来,确保这部分是干净的,再去动插件目录。

TaoToken 在这里的角色是统一模型入口。你不需要在 OpenClaw 里为每个模型单独配一套鉴权,而是把 Base URL 指向https://taotoken.net/api,用同一个 Key 去调不同模型。这样排查插件问题时,模型侧只有一个变量,不会互相干扰。

具体操作路径:

  1. 打开https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_speech_core创建 API Key。
  2. 在 OpenClaw 的模型配置里填入 Base URL 和 Key。
  3. 用https://taotoken.net/api作为统一入口,不要带 UTM 后缀,那是给页面跳转用的。

如果你用的是 Claude Code 或 Cline 这类工具,配置逻辑一样,只是配置文件位置不同。OpenClaw 的模型配置通常在~/.openclaw/config.json或项目根目录的openclaw.config.json里,字段名可能是baseUrl、apiKey、model。下面给一个可复制的 JSON 片段,路径按你实际安装位置调整:

{ "model": { "provider": "openai-compatible", "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoToken密钥", "modelId": "claude-sonnet-4-20250514" }, "plugins": { "speech-core": { "enabled": true, "runtimePath": "./dist/extensions/speech-core/runtime-api.js" } } }

注意runtimePath这一项,很多同学报Unable to resolve就是因为这里写的是绝对路径,但换机器或升级后路径变了。建议用相对路径,或者干脆删掉这一项让 OpenClaw 走默认解析。默认解析会去dist/extensions/<plugin-name>/runtime-api.js找,只要文件在,就能加载。

模型侧验证是否通了,可以用模型对话页面直接测:https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_speech_core。发一句“你好”,能正常返回就说明 Base URL 和 Key 没问题。这一步过了,再回去看插件报错,就能确定问题纯粹在 OpenClaw 本地文件层。

如果你打算长期跑 Agent 任务,比如让 OpenClaw 持续处理消息队列,可以考虑 Coding Plan,入口在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_speech_core。它的好处是额度稳定,不会因为单次请求波动导致 Agent 中途断掉,排查插件时少一个干扰项。

模型接入层理顺之后,接下来才是真正的插件目录检查。记住一个原则:模型侧只留一个变量,插件侧只改一个路径,两边不要同时动。

3. 可复制的插件目录检查与 runtime-api.js 路径修复

这一节是核心操作。先给一套完整的检查命令,按顺序执行,每一步的输出都决定下一步怎么走。

3.1 确认 OpenClaw 安装根目录

不同安装方式根目录不一样。npm 全局安装通常在:

  • Windows:C:\Users\<用户名>\AppData\Roaming\npm\node_modules\openclaw
  • macOS/Linux:/usr/local/lib/node_modules/openclaw或~/.npm-global/lib/node_modules/openclaw

用命令直接定位:

npm root -g

输出就是全局 node_modules 路径,后面拼/openclaw即可。进入这个目录:

cd $(npm root -g)/openclaw ls -la

你应该能看到dist/、package.json、openclaw.mjs这些。如果openclaw.mjs不在,说明主包安装不完整,直接跳到 3.5 重装。

3.2 检查 speech-core 插件目录

ls -la dist/extensions/speech-core/

正常应该看到runtime-api.js、index.js、package.json等。如果这个目录不存在,或者runtime-api.js缺失,就是报错的直接原因。

再确认文件确实可读:

cat dist/extensions/speech-core/runtime-api.js | head -20

能打印出内容说明文件完好。如果报No such file or directory,就是文件丢了。

3.3 核对插件注册表

OpenClaw 内部有一份 bundled plugin 注册表,通常在dist/extensions/registry.json或类似位置。查看:

cat dist/extensions/registry.json | grep -A3 speech-core

确认里面登记的路径和实际文件路径一致。如果注册表写的是speech-core/runtime-api.js,但实际文件在dist/extensions/speech-core/runtime-api.js,那解析基准目录就很重要。OpenClaw 默认以dist/extensions/为基准,所以注册表里的相对路径应该是speech-core/runtime-api.js。

3.4 修复配置

如果文件在,但配置里runtimePath写错了,改配置文件。以openclaw.config.json为例:

{ "plugins": { "speech-core": { "enabled": true, "runtimePath": "speech-core/runtime-api.js" } } }

注意这里不要写./dist/extensions/前缀,因为 OpenClaw 会自己拼基准目录。写了反而变成dist/extensions/dist/extensions/speech-core/runtime-api.js,照样报Unable to resolve。

如果你用的是 TOML 配置(部分版本支持),写法:

[plugins.speech-core] enabled = true runtimePath = "speech-core/runtime-api.js"

改完保存,不要急着启动,先跑一次诊断:

openclaw doctor --fix

doctor 会扫描插件目录,把无效的 runtimePath 隔离掉,并输出它认为正确的路径。如果 doctor 也报Cannot find module ...openclaw.mjs,说明主包已经损坏,直接走重装。

3.5 重装主包

npm uninstall -g openclaw npm cache clean --force npm install -g openclaw

卸载时如果遇到EPERM权限警告,通常是文件被占用,关掉正在运行的 OpenClaw 进程和杀毒软件实时扫描,再重试。重装完成后:

openclaw --version

能打印版本号,说明主包恢复。然后再检查插件目录:

openclaw plugins list --enabled --verbose

这个命令会列出所有已加载的 bundled plugin,speech-core 应该在列表里,且状态是 enabled。如果它显示 missing 或 error,继续看下一节。

3.6 版本错配的处理

如果你是从 Beta 版降级或升级过来,可能出现新旧文件混用。典型表现是dist/extensions/下同时存在speech-core和speech-core.bak,或者runtime-api.js是旧版本的。处理方式:

rm -rf dist/extensions/speech-core npm install -g openclaw@2026.4.29

指定一个稳定版本重装,让 npm 重新拉取完整的 dist 目录。装完再跑openclaw plugins inspect speech-core --runtime --json,看输出的resolvedPath是否指向真实存在的文件。

这一套下来,大部分Unable to resolve bundled plugin speech-core/runtime-api.js都能解决。核心就一句话:文件要在,路径要对,注册表要一致。三者缺一,就会报这个错。

4. 重启网关并验证插件加载成功

配置改完、文件补齐之后,不能只看日志不报错就完事,要确认插件真的注册进运行时了。下面是一套验证动作,按顺序做。

4.1 启动网关并跟踪日志

openclaw gateway --verbose

另开一个终端跟踪日志:

openclaw logs --follow

观察启动阶段有没有speech-core相关的 resolve 记录。正常输出类似:

[plugin] resolving bundled plugin speech-core [plugin] runtime entry resolved: /path/to/dist/extensions/speech-core/runtime-api.js [plugin] speech-core registered

如果看到Unable to resolve再次出现,说明路径还是不对,回到第 3 节重新核对。

4.2 用 inspect 命令确认运行时状态

openclaw plugins inspect speech-core --runtime --json

输出是一个 JSON,重点看三个字段:

{ "id": "speech-core", "enabled": true, "resolvedPath": "/usr/local/lib/node_modules/openclaw/dist/extensions/speech-core/runtime-api.js", "status": "loaded" }

status是loaded才算成功。如果是missing或error,resolvedPath会显示它尝试找的路径,拿这个路径去文件系统里核对,就能定位差在哪一级目录。

4.3 触发一次 Agent 会话

插件加载成功不代表 Agent 会话一定通,还要验证模型侧和插件侧协同工作。发一条测试消息:

openclaw agent send --message "测试会话"

如果返回正常回复,说明整条链路通了。如果返回Agent failed before reply,但日志里没有Unable to resolve,那问题就转移到模型接入层,回去检查第 2 节的 Base URL 和 Key。

4.4 检查端口占用

网关默认端口 18789,确认它真的在监听:

netstat -ano | findstr :18789

Windows 下用findstr,macOS/Linux 用grep。有 LISTENING 状态说明网关起来了。如果端口被占用,换端口启动:

openclaw gateway --port 18790

4.5 验证插件列表

openclaw plugins list --enabled --verbose

输出里 speech-core 应该显示 enabled,且没有 warning。如果它显示 disabled,检查配置文件里是不是被手动关了。有些同学在排查时把enabled改成 false,修完忘了改回来,结果插件不加载,又以为是路径问题。

4.6 长期运行的稳定性检查

如果你打算让网关常驻,建议加一个定时诊断:

openclaw doctor --fix

可以写成 cron 或计划任务,每天跑一次。doctor 会清理过时的插件状态,隔离无效配置,避免某次升级后文件错位又导致启动失败。我自己的做法是每周跑一次,配合日志轮转,基本没再遇到过Unable to resolve这类问题。

验证这一步的关键是:不要只看“没报错”,要看“状态是 loaded”。日志不报错可能只是错误被吞了,inspect 的 JSON 输出才是硬证据。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

修speech-core/runtime-api.js的过程中,很容易顺带撞上其他报错。这一节把高频错误和对应动作列清楚,避免你在一堆日志里迷失。

5.1 401 Unauthorized

现象:Agent 会话返回 401,日志里模型请求被拒。

原因:TaoToken 的 Key 没填对,或者 Base URL 写成了带 UTM 的页面地址。注意 API 入口是https://taotoken.net/api,不要带?utm_source=...那串,那是给网页跳转用的,API 请求带上会解析失败。

修复:检查配置文件里的apiKey和baseUrl,Key 重新从https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_speech_core复制一次,确保没有多余空格。

5.2 local proxy failed

现象:日志出现local proxy failed,模型请求发不出去。

原因:OpenClaw 本地代理层配置了错误的转发地址,或者端口冲突。常见于同时开了多个网关实例。

修复:确认只有一个 gateway 进程在跑,检查netstat看端口占用。如果配置里写了自定义 proxy,先注释掉,走直连https://taotoken.net/api测试。

5.3 reading choices 报错

现象:Cannot read properties of undefined (reading 'choices')。

原因:模型返回体格式和 OpenClaw 预期不一致。通常是 Base URL 指向了一个不兼容 OpenAI 格式的端点,或者模型 ID 写错导致返回了错误结构。

修复:确认baseUrl是https://taotoken.net/api,modelId用平台支持的模型名。用模型对话页面先测一次,确认返回结构正常,再填回 OpenClaw。

5.4 OAuth 相关报错

现象:OAuth token expired或OAuth callback failed。

原因:如果你用的是 Claude Code 或 Codex 这类带 OAuth 的工具,token 过期或回调地址不对。

修复:重新走一次授权流程。如果是 Codex 的auth.json,确认里面的base_url指向https://taotoken.net/api,api_key字段填 TaoToken 的 Key。三件套要齐全:Base URL、Key、Model ID,缺一个都会报错。

5.5 插件报错和模型报错同时出现

这是最麻烦的情况。日志里既有Unable to resolve bundled plugin,又有 401。处理顺序:先修插件,再修模型。因为插件加载失败会导致网关初始化中断,模型请求根本发不出去,这时候看到的 401 可能是假象。

修完插件,重启网关,确认plugins inspect状态是 loaded,再发测试消息。如果这时才出现 401,那才是真的 Key 问题。

5.6 对照表

报错根因动作
Unable to resolve bundled plugin插件文件缺失/路径错检查 dist/extensions,修 runtimePath
401Key 或 Base URL 错重填 TaoToken Key,Base URL 用 /api
local proxy failed代理配置冲突关多余进程,走直连
reading choices返回体格式不符核对 modelId 和 baseUrl
OAuth failedtoken 过期重新授权,检查 auth.json

这张表建议存下来,下次遇到直接对号入座。核心原则还是那句:先确认 CLI 活着,再确认插件加载,最后确认模型通。顺序反了,排查时间翻倍。

6. 把配置固定下来,下次升级不慌

修好之后,建议做两件事,避免下次升级又踩同样的坑。

第一,把当前可用的配置备份一份。OpenClaw 的配置文件、插件目录列表、TaoToken 的 Base URL 和 Key(Key 不要明文提交到 git),存到一个本地笔记里。升级前先对比,升级后如果报错,直接回滚配置。

第二,升级前先跑openclaw doctor --fix,让它把当前状态记录一遍。升级后再跑一次,对比输出差异。如果 doctor 报出新的 missing 插件,提前处理,不要等启动失败才动手。

如果你需要长期跑 Agent,模型侧用 Coding Plan 固定额度,入口在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_speech_core。插件侧保持dist/extensions/目录干净,不要手动往里塞文件,所有 bundled plugin 都让 npm 安装时自动铺好。

最后给一个日常检查命令,贴在终端里随时跑:

openclaw --version && openclaw plugins inspect speech-core --runtime --json | grep status

输出loaded就放心用。如果哪天又看到Unable to resolve,回到第 3 节,从ls dist/extensions/speech-core/开始查,五分钟内能定位。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询