Skip to content

插件加载失败:ENOENT 找不到 package.json(cache 目录结构不一致)

问题

安装插件后,opencode 启动时报如下错误,插件始终无法加载:

ERROR service=plugin path=<plugin-name>@latest error=ENOENT: no such file or directory,
open /home/user/.cache/opencode/packages/<plugin-name>@latest/node_modules/package.json
failed to resolve plugin server entry

使用 GitHub shorthand 格式(如 Edison-A-N/opencode-preview)时还会出现另一种变体:

ERROR service=plugin path=Edison-A-N/opencode-preview error=ENOENT: no such file or directory,
open /home/user/.cache/opencode/packages/Edison-A-N/opencode-preview/node_modules/Edison-A-N/package.json
failed to resolve plugin server entry

重启 opencode 无法自愈,每次都报同样的错误。

涉及版本:opencode v1.14.18 ~ v1.14.21+,Linux。

原因

PR #18308(commit c9326fc19)将插件安装从 BunProc 改为 @npmcli/arborist 后,引入了两个 bug:

Bug 1 — 路径解析层级错误Npm.add()resolveEntryPoint() 中,arborist 安装完成后调用 loadVirtual()first.path 返回的是 wrapper 目录(packages/<name>@latest/),而非实际包目录(packages/<name>@latest/node_modules/<name>/)。插件加载器因此读到了 wrapper 层的 package.json(只有 {"dependencies":{...}},没有 main/exports),导致入口解析失败。

Bug 2 — 残留空目录导致永久失败:commit f27eb8f09 加入了 existsSafe(dir) 检查,若 cache 目录已存在则跳过 arborist 重新安装。问题在于只检查目录是否存在,不检查 node_modules 是否完整。若 arborist 中途失败(网络超时、进程被杀),会留下空的 packages/<name>@latest/ 目录,此后每次启动都跳过安装 → 同一个 ENOENT 永久复现,插件无法自愈。

Bug 3 — GitHub shorthand 包名解析错误npa("Edison-A-N/opencode-preview") 解析为 GitHub 类型时 hit.namenull,fallback 使用原始 spec 字符串作为包名,生成无效路径 node_modules/Edison-A-N/package.json

解决方案

临时修复:清空 cache 目录重新安装

手动删除损坏的 cache 条目,让 opencode 下次启动时重新安装插件:

bash
# 删除单个插件的 cache
rm -rf ~/.cache/opencode/packages/<plugin-name>@latest/

# 或者清空整个插件 cache(谨慎,会重装所有插件)
rm -rf ~/.cache/opencode/packages/
rm -rf ~/.cache/opencode/node_modules/

删除后重新启动 opencode,插件会自动重新安装。

注意:若网络不稳定导致安装再次中途失败,需再次手动清理。

等待官方 patch

该问题已在 GitHub #23502 追踪,官方正在修复 resolveEntryPoint() 中的路径层级判断和 existsSafe 检查逻辑。

来源:GitHub #23502