DSH plugin 报 reading 'prepare' 怎么修?DeepSeek Harness 排查与修复

故障排查发布于 2026-10-12作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSH plugin报错排查工具调用依赖冲突dsh-tools
装了依赖 @deepseek-ai/dsh-tools 的第三方 DSH plugin 后,每次工具调用都报 Cannot read properties of undefined (reading 'prepare')。这篇讲清报错含义、三步取证定位与三类根因处置。

如果你在装完某个第三方 DSH plugin 之后,每次工具调用都报 TypeError: Cannot read properties of undefined (reading 'prepare'),界面显示「本轮运行失败」,先别急着重装整套环境。 这条报错表达的不是「插件功能出错」,而是工具调度层拿到了一个没有被正确装配的注册表对象:代码去读它的 prepare 方法,结果拿到 undefined。诱因通常在装配环节——某个插件把核心工具包又解出了一份副本(来源:Discussion #1486)。这篇按三个方向讲清:① 报错的确切含义与典型症状;② 用三步取证把范围收窄到具体插件;③ 三类常见根因各怎么处置。插件之间的依赖关系怎么看,可对照《插件重复核心包怎么修》。

DSH plugin 报 reading 'prepare' 是什么意思:先把报错读准

这条报错是 JavaScript 运行期错误,说的是代码从一个 undefined 上读属性;出现在工具调用早期,意味着问题在调度层而非具体工具(来源)。 把报错原文拆开看:

text
TypeError: Cannot read properties of undefined (reading 'prepare')
    at ToolDispatcher.dispatch (.../tool-dispatch.js:...)
    at async SessionRunner.runTurn (.../session-runner.js:...)

三个信息点决定了排查方向:

信息点含义指向
Cannot read properties of undefined有个对象是 undefined装配缺失,不是工具逻辑错
reading 'prepare'读的是 prepare 方法被读的是工具注册表/调度器对象
栈顶在 dispatch / runTurn报错发生在每次调用的必经路径全局失败,不是单个工具的问题

社区报告里的症状形状正好吻合:装了依赖 @deepseek-ai/dsh-tools 的第三方插件后,任意对话都会在工具调用阶段失败,界面显示「本轮运行失败」;而 headless profile 一切正常(来源:Discussion #1486)。「每次都失败」+「换个 profile 就好」这两个特征,是把它和「某个工具用不了」「模型连不上」区分开的关键。

DeepSeek Harness 里这个报错怎么定位:三步取证

定位顺序是「先确认范围、再查依赖、最后二分插件」,每一步都产出可证伪的结论,避免直接动手重装。 具体做法:

  1. 确认失败范围。 新建一个会话,只让它调用一个最基础的读文件类工具;再切到 headless profile 跑同一句话。记下两点:是不是每次调用都失败、headless 是否正常。若 headless 正常,嫌疑就锁定在 web profile 额外装载的那批插件上(来源:Discussion #1486)。
    • 预期:得到「全局失败 + 仅 web 失败」或「局部失败」的明确结论,而不是「就是报错了」。
  2. 查依赖树里有几份核心工具包。 在你的插件目录下执行依赖树查询,看 @deepseek-ai/dsh-tools 出现了几次、版本是否一致。
    bash
    npm ls @deepseek-ai/dsh-tools --all
    
    • 预期:若输出里出现两条不同的解析路径(例如一份来自框架自身、一份来自某插件的 node_modules),就基本命中根因——重复解析(来源:Discussion #1337)。
  3. 用二分法把嫌疑收窄到单个插件。 在配置里停掉最近新增的一半第三方插件,重启 dsh web 复测;报错消失就对这半继续二分,反之查另一半。
    bash
    dsh plugin --profile web list
    dsh plugin --profile web remove <可疑插件>
    
    • 预期:最终锁定到一个具体插件名,并能用「装上就报、卸掉就好」稳定复现。

三步走完,你手上会有一句可复现的结论,例如「装 X 插件后,web profile 下每次工具调用报 prepare 错,卸载即恢复」。有这样的结论再去修,才不会在重装里反复兜圈子。

三类常见根因与对应的 DSH plugin 处置办法

绝大多数同类报错可归为三类:核心包重复解析、插件与核心版本不匹配、插件自身初始化缺失;三类的处置动作完全不同。 对照下表处理:

根因判定依据处置办法
核心包重复解析npm ls 里同一包出现两条路径统一到框架自身那份;对冲突插件改用不内联核心包的版本,或换用替代插件
插件与核心版本不匹配插件声明的 peer 版本与当前框架版本不符把插件升/降到与核心匹配的版本,或先升级框架再装插件
插件初始化缺失该插件在 web profile 下未按其约定完成注册按插件文档补齐配置与初始化步骤,确认它在 dsh plugin list 中状态正常

第一类是最常见的。它的机制是:插件在自己的依赖里又装了一份 @deepseek-ai/dsh-tools,于是插件注册到的是 A 副本的注册表,而调度层读的是 B 副本——两边不是同一个对象,prepare 自然读不到(来源:Discussion #1337)。处置原则是「让核心包只有一份」,而不是把报错按下去。第二、三类则分别对应版本与初始化,通常升级插件或补配置即可。

修 DSH plugin 这个报错时的注意事项

  1. 先取证再动手。 在拿到「哪个插件、在哪个 profile、能否稳定复现」之前,重装只是把同一个冲突原样装回来。
  2. 善用 headless 做对照。 同一句话在 headless 下跑通,就说明核心链路没坏,问题在 web 侧的插件装配。
  3. 不要靠删报错或用 try/catch 掩盖。 调度层的对象缺失是装配问题,压掉报错只会让后续行为更不可预测。
  4. 回退优于硬修。 若某插件与当前核心版本冲突且暂无匹配版本,先卸载并改用功能重叠的替代插件,是更稳的选择;替代方案可参考 DSH Plugin Hub。
  5. 修完做一次回归。 至少跑一次完整的多步工具调用(读文件 → 改文件 → 执行命令),确认调度层在连续调用下也正常。
工具调度层报 prepare 错误的排查流程示意

来源:Discussion #1486、Discussion #1337、DeepSeek Harness 官方文档 - 工具子系统

常见问题

DSH plugin 报 reading 'prepare' 这个错误,到底是插件坏了还是框架坏了?

DSH plugin 报 reading 'prepare',多数不是插件自己坏了,而是工具调度层拿到了一个「不是自己那份」的工具注册表对象。 这条错误是 JavaScript 运行期报错:代码去读某个对象的 prepare 方法,但那个对象是 undefined。它出现在工具调用早期、而不是某个具体工具内部,说明问题出在「谁来调度工具」这一层,而不是「工具怎么干活」。

DeepSeek Harness 里为什么装完第三方插件后,每一次工具调用都会失败?

DeepSeek Harness 每次工具调用都失败,是因为所有调用都要先经过同一个工具调度层,那一层坏了,谁都跑不起来。 社区报告里,装了某个依赖 @deepseek-ai/dsh-tools 的第三方插件后,任意对话都会在本轮运行时报错,界面显示「本轮运行失败」;而 headless profile 却正常。这种「全局失败、换 profile 就好」的形状,是判断问题出在装配层而不是工具的强信号(来源:Discussion #1486)。

为什么 headless profile 正常,只有 web profile 报这个 DSH plugin 错误?

headless 正常而 web 报错,说明冲突来自 web profile 那套额外的插件装配,而不是核心工具链本身。 两个 profile 加载的插件集合不同:web profile 会额外装载一批提供界面与交互能力的插件,如果其中某个把核心工具包又解出了一份,冲突就只在 web 这一侧显形。反过来,这也给了你一个现成的对照实验——用同一个插件在 headless 下跑一遍,就能把嫌疑范围收窄到「web 侧新增的那批依赖」上。

修 DSH plugin 这个 reading 'prepare' 报错,第一步到底该做什么?

第一步是取证而不是重装:确认失败范围,再看依赖树里有没有第二份核心工具包。 先把「是不是每次工具调用都失败」「headless 下是否正常」这两点记下来,它们决定了问题是全局还是局部。然后检查插件依赖树里 @deepseek-ai/dsh-tools 被解析了几份——社区报告的根因就是多解出了一份副本。没有这一步,重装往往只是把同一个冲突原样装回来。

不想深挖依赖树,有没有更快的办法让 DSH plugin 恢复正常?

最快的办法是二分法:逐个停用最近新增的插件,找出装到哪一个开始报错。 先在配置里把最近加入的第三方插件停掉、重启 dsh web,看报错是否消失;消失就说明嫌疑在这批里,再对半拆开继续缩小。定位到具体插件后,优先把它升到与当前核心版本匹配的版本,或者暂时卸掉、改用功能重叠的替代插件。

相关术语

TypeError: Cannot read properties of undefined
JavaScript 运行期错误,表示代码试图从一个 undefined 值上读取属性或调用方法。本文语境里,被读的是工具注册表对象的 prepare 方法,说明该对象没有被正确装配出来。— https://github.com/deepseek-ai/deepseek-harness/discussions/1486
tool dispatch layer(工具调度层)
DeepSeek Harness 中负责接收模型发出的工具调用、在真正执行前做路由与把关的那一层。它在每次工具调用早期运行,因此它一坏,表现就是「每次调用都失败」而不是某个工具单独出错。— DeepSeek Harness 官方文档 - 工具子系统
duplicate core package(核心包重复)
指同一份核心包(如 @deepseek-ai/dsh-tools)在依赖树里被解析出多个副本。不同副本之间实例与注册表不互通,插件拿到 A 副本、调度层用 B 副本时就会读到 undefined。— https://github.com/deepseek-ai/deepseek-harness/discussions/1337
profile
DeepSeek Harness 的插件装载集合,常见的有 web 与 headless。不同 profile 加载的插件不同,所以同一套代码可能在 web 下报错、在 headless 下正常,这也是排查时最好用的对照变量。— https://github.com/deepseek-ai/deepseek-harness/discussions/1486

来源