DeepSeek Harness 报 "reading 'prepare'" 错误?插件重复核心包排查

故障排查发布于 2026-08-27作者: DSH Plugin 插件中心
DeepSeek HarnessDSH pluginreading prepare重复核心包工具调用报错
DeepSeek Harness 报 reading 'prepare' 崩溃?根因是 profile 内出现第二份 @deepseek-ai/dsh-tools,Symbol 键不相等。一条 find 命令定位重复核心包,清理即恢复。

DeepSeek Harness 报 Cannot read properties of undefined (reading 'prepare') 且所有工具调用都失败,根因通常是 profile 里出现了第二份 @deepseek-ai/dsh-tools——工具调度器用模块内 Symbol() 做键,两份副本键不相等,查回来就是 undefined。 一条 find 命令就能定位,清理后即恢复;但已遗留 tool_calls 的会话救不回来,只能放弃。

DeepSeek Harness 报 reading 'prepare' 错误长什么样

报错固定为 UNKNOWN: Cannot read properties of undefined (reading 'prepare'),发生在每个工具调用上,且加载时不报任何错。 有用户实跑遇到(讨论原文),现象如下:

  1. profile 启动正常,但让 Agent 调用任何工具都抛 Cannot read properties of undefined (reading 'prepare')
  2. 报错不点名是哪个工具、也不点名是哪个包重复——用户第一反应通常是怀疑框架或模型提供方坏了;
  3. 更麻烦的是二次伤害:失败的 turn 把 tool_calls 写进了日志却没有对应结果,下一轮请求直接被模型提供方拒绝(An assistant message with 'tool_calls' must be followed by tool messages...),整个会话不可恢复。

这个报错之所以难查,是因为问题藏在依赖解析里,而不是运行时逻辑里TOOL_RUNTIME_SCHEDULER 是一个模块内 Symbol()dsh-tools 定义处),Symbol() 的身份按模块实例隔离,读方和写方必须解析到同一个 dsh-tools 文件。profile 里一旦多出一份副本,两边用的键就不再相等(来源)。

DSH 插件重复核心包:为什么一个包会装出两份

第二份核心包有三个来源:插件把核心包声明为直接依赖、tarball 打包带出传递副本、早期安装遗留的 node_modules。 逐个说明:

  1. 插件把 @deepseek-ai/* 声明成直接依赖:正确做法是放进 peerDependencies,依赖树只解析一份;写成 dependencies 就会在 profile 里装出第二份;
  2. 打包 tarball 安装:把 dsh 本体以 packed tarball 装进 profile 时最容易带出重复的传递副本,尤其当某个包声明了过宽的 peer 范围;
  3. 遗留的 node_modules:最隐蔽的一种——报告者的 headless profile 依赖全空、问题插件也不在 bundles 里,只是早期安装残留了一棵 node_modules/@deepseek-ai/ 树,工具调用照样每轮失败。把残留目录移开后立即恢复(mv ~/.dsh/profiles/headless/node_modules/@deepseek-ai /tmp/backup/)。

所以「卸载插件」并不够——只要 node_modules 里还躺着副本,profile 就一直坏着,而且没有任何配置能提示你原因。

怎么排查重复核心包:一条 find 命令

定位方法是一条 find:profile 的 node_modules 里不应该解析出任何 @deepseek-ai 核心包——核心来自 CLI 自己的依赖树,profile 只该放插件。 按步骤查:

  1. 找出 profile 目录,确认目标 profile 名:
bash
ls ~/.dsh/profiles/
  1. 检查 dsh-agent 副本,应无任何输出
bash
find ~/.dsh/profiles/<name>/node_modules -maxdepth 4 -path '*/@deepseek-ai/dsh-agent' -print
  1. 再查 dsh-tools,应同样无输出:
bash
find ~/.dsh/profiles/<name>/node_modules -maxdepth 4 -path '*/@deepseek-ai/dsh-tools' -print
  1. 有输出 = 装了两份:把找到的目录记下来,删掉或移到备份目录:
bash
mv ~/.dsh/profiles/<name>/node_modules/@deepseek-ai /tmp/dsh-backup/
  1. 重启 dsh(Ctrl+C 后重新 dsh web),新会话里让 Agent 调用一次工具——不再报 reading 'prepare' 即修复。

报告者实测:移动整个 node_modules/@deepseek-ai 目录(而非逐个包)即可一次清干净,同一命令换 dsh-agent / dsh-tools 重复执行确认无残留。

修复与预防:清理重复核心包与 DSH 插件依赖规范

修复方向分两层:官方把键改成跨副本一致的 Symbol.for()(配合协议版本守卫),插件作者把核心包放 peerDependencies。 社区已确认根因并给出建议(来源):

  1. 键改成 Symbol.for('@deepseek-ai/dsh-tools.scheduler'):让两份副本算出同一个键,硬失败降级为"仅冗余安装";
  2. 加协议版本守卫Symbol.for 只是解决了访问问题,不同版本的副本会共享同一个键——如果调度器形状跨版本变化,响亮崩溃会变成静默错配,所以注册方要盖版本戳、读方校验并报出双方版本号;
  3. 加载时大声失败:组合 profile 时对每个 @deepseek-ai/* 包做 realpath 校验,一个包解析出多个路径就直接报错,而不是等运行时炸;
  4. 插件作者契约:dsh-context 是正确范例(dependencies: {},所有 @deepseek-ai/* 与 react/zod 放 peerDependencies),官方文档应把这条写死,dsh plugin add 检测到插件把核心包声明为非 peer 依赖时给出警告。

在官方修复落地前,按本文的 find 清理即可恢复。这条排查逻辑也说明插件来源可信很重要——安装目录中经过人工验证的插件会少很多这类打包问题。如果你不想手动跟依赖树打交道,DeepSeek Harness 桌面端内置的 DSH Plugin Hubdsh-plugin.org)集中管理已装插件,装了什么一目了然,还能一键卸载清理。

注意事项

  1. 报错发生在「有第二份核心包」时,先跑 find 再怀疑模型或框架,别在错误方向上空耗。
  2. 清理后必须开新会话:旧的失败会话已遗留 tool_calls 无结果,模型提供方会持续拒绝。
  3. 有多个 profile 时逐个检查,任何一个 profile 的残留都会让该 profile 工具调用全挂。
  4. 同类插件报错还汇总在《DeepSeek Harness 插件报错合集:DSH plugin 不加载、Web UI 异常与会话缓存修复》里。

来源:Discussion #4640packages/core/tools(dsh-tools)

常见问题

DeepSeek Harness 报 Cannot read properties of undefined (reading 'prepare') 且所有工具调用失败是什么原因?

profile 的 node_modules 里出现了第二份 @deepseek-ai/dsh-tools。工具调度器用一个模块内 Symbol() 做键,两份副本的键不相等,agent loop 从另一份构造的服务里查调度器返回 undefined(来源)。

为什么 profile 的 node_modules 里会多出一份 @deepseek-ai 核心包?

最常见是插件把 @deepseek-ai/* 声明成直接依赖(正确做法是放 peerDependencies);其次是打包 tarball 装进 profile 时带出传递副本;还有一种是早期安装遗留的 node_modules——即使 profile 已不引用它,残留的副本照样破坏工具调用。

怎么用 find 命令定位重复的 @deepseek-ai/dsh-tools 核心包?

用 find 检查 profile 的 node_modules:find <profile>/node_modules -maxdepth 4 -path '*/@deepseek-ai/dsh-agent' -print 应无输出;把 dsh-agent 换成 dsh-tools 再查一遍。有输出就是装了两份,mv 到备份目录后重启 dsh web 即可恢复。

工具调用报 reading 'prepare' 失败后,这个会话还能继续用吗?

不能用。失败的 turn 会遗留 tool_calls 却没有对应结果,下一轮请求会被模型提供方以 "An assistant message with 'tool_calls' must be followed by tool messages" 拒绝,会话只能放弃、开新会话。

重复核心包导致报错后怎么恢复?清理和重启的具体步骤?

清理重复副本即可恢复:删除或移走 profile 下残留的 node_modules/@deepseek-ai 副本(如 mv ~/.dsh/profiles/<name>/node_modules/@deepseek-ai /tmp/dsh-backup/),重启 dsh(Ctrl+C 后重新 dsh web)后新会话工具调用恢复正常;已损坏的旧会话放弃。

来源