DeepSeek Harness 子代理排查:codex 只报 product-error、条目删不掉与结算崩溃
DeepSeek Harness(DSH)的子代理在「好用的时候很省事、坏起来很难查」之间有明显的落差,本批讨论里有四种典型形态:失败只给一句 Product subagent failure (product: Codex; stage: turn; category: product-error) 而没有任何底层细节;同一个任务用 Codex CLI 能完成、用 subagent_codex 却失败(内置 Codex 版本比用户的配置旧);删掉子代理的会话目录之后界面条目清不掉;以及最严重的一种——continuable 子代理在结算阶段读收件箱抛异常,把整个进程带成致命退出(exit 1),十几分钟必现。 前三种是「能查但有门槛」,最后一种是「稳定性问题」,处理优先级最高(#9640、#9346、#9552、#8849)。 另外,如果子代理的症状是控制类工具像被换了一套、按 id 寻址失败,那属于「工具被 Team 版替换」的另一族问题,见 DeepSeek Harness Agent Teams 冲突:list_agents 同名与子代理停不掉。
DeepSeek Harness 只报 product-error:细节在投影阶段被折叠掉了
一句话结论:适配器把几种不同的底层错误一并折叠成 product-error,真实的错误标识在这一步就被丢掉;而诊断渲染又只输出固定字段——完整原因虽然还留在失败实例上,却没有任何地方去读它。 于是你拿到的永远是一句没有信息量的类别名(#9640)。
DeepSeek Harness 四步把细节捞出来
- 先确认「同任务换个入口能成」:如果同样的任务用 Codex CLI 直接跑能完成,说明问题在适配层的通信/分类,而不是任务本身(#9640)。
- 抓 app-server 通信。社区插件
@argszero/dsh-codex-wire-capture会把 app-server 的 stdout 分流保存,从而拿到被折叠掉的codexErrorInfo(#9640):
npm i @argszero/dsh-codex-wire-capture
- 按拿到的错误标识查含义,再决定是模型不支持、参数不合法,还是上游回滚引起的失败(#9640)。
- 判读
stage: turn的边界:它只能告诉你「失败在本轮执行阶段」,不能替代具体错误;看到它不要就此停手(#9640)。
DeepSeek Harness 版本错配:内置 Codex 比你的配置旧
一句话结论:subagent_codex 会沿用本机 Codex 的配置文件(例如默认模型名),而宿主内置的 Codex 二进制可能是较旧版本,读不懂这个模型,于是启动或首轮就失败——同任务用 CLI 能成,正是因为它用的是你本地那个更新的版本。(#9346) 这类「子代理跑的模型或版本和你以为的不一样」的错配(包括模型继承与推理档不传导),在 DSH plugin 子代理用错模型?subagent 模型继承与排查方法 里有更完整的梳理。
DeepSeek Harness 诊断四件套(对齐这四项,问题通常立刻现形)
- 解析出的可执行路径:确认子代理实际调用的是哪个 Codex,而不是你以为的那个。
- 它的版本号:直接执行
codex --version对照宿主内置版本。 - 生效的
CODEX_HOME:确认读的是哪一份配置(同一台机器上可能存在多份)。 - 解析后的模型名:把配置文件里声明的默认模型与「该版本支持的模型」对照(#9346)。
DeepSeek Harness 三条处置
DeepSeek Harness 删了会话目录,界面条目还在
一句话结论:子代理记录已经改成「写在父会话日志里的目录事件 + 一个投影」,而事件、投影、查询与工具四层都没有移除路径**——记录是只追加的,所以删磁盘目录不会让界面条目消失。** 讨论中做了对照:8 月这样做是有效的、10 月(0.2.0-rc.2)起无效,同一个 UUID 对比(#9552)。
DeepSeek Harness 处置
- 确认判据:删除子代理的会话目录后,刷新与重启都不再清除该条目;而工作区列表与会话文件本身正常(#9552)。
- 目前没有用户侧规避:讨论明确说明插件也做不到——折叠逻辑会忽略其它事件类型,客户端插件最多只能做显示层隐藏(#9552)。
- 可接受的替代做法:把不再需要的子代理会话归档或重命名,用「过滤/排序」减少干扰,而不是试图删除记录。
- 诉求方向(供反馈上游):新增
subagent/retire这类事件 + 折叠时过滤 + 查询与工具跟随(#9552)。
DeepSeek Harness 结算期异常把整个进程带崩
一句话结论:continuable 子代理结算阶段读收件箱时,读取函数在状态取不到值的情况下直接抛出**,而调用它的结算逻辑是一个没有捕获的异步立即执行函数——异常逃逸成未处理拒绝,整个进程致命退出。** 特征是时间上十几分钟必现、崩溃栈能映射到收件箱读取与结算激活两处源码(#8849)。
DeepSeek Harness 四步处置(按优先级)
- 确认判据:宿主运行十几分钟后无预警退出,退出码为 1;日志里能看到未处理拒绝,栈指向收件箱读取与结算激活(#8849)。
- 规避(当前唯一有效):回退到不启用 continuation / activation 机制的旧版本——问题就在这条结算链路上(#8849)。
- 无法回退时:用外部守护进程自动拉起,把「不可用」降级成「可恢复」;但要注意这会中断所有进行中的会话(#8849)。
- 记住两层缺陷:一是读取路径不该在「状态未定义」时抛;二是顶层异步立即执行函数必须有兜底。讨论里还指出——「缺日志」本身也是缺陷,因为崩溃前没有任何可用线索(#8849)。
DSH插件 排查注意事项
子代理问题的排查顺序建议:先排除「进程级稳定性」(会不会自己退出),再看「版本错配」,最后才是「诊断信息不足」。 八条要点:
- 十几分钟必现的退出优先按致命退出处理,别先花时间查诊断文案(#8849)。
product-error的语义是「分类失败」,不等于「产品缺陷」(#9640)。stage: turn只缩小范围,不定位原因(#9640)。- 「CLI 能成、子代理不成」是版本错配的指纹(#9346)。
- 诊断四件套要一起看:可执行路径、版本、
CODEX_HOME、模型名,缺一项都容易误判(#9346)。 - 本机改写插件文件会被升级覆盖,要记进自己的变更清单(#9346)。
- 子代理记录是只追加的:删目录 ≠ 删记录,别再指望重启能清掉界面条目(#9552)。
- 修复状态如实:四条在讨论所指版本(
0.2.0-rc.2)里都未修;社区插件能补诊断(抓 wire),但版本错配、条目退役、结算崩溃都需要核心侧改动。
子代理这类问题经常和「装了什么、什么版本」直接相关,尤其版本错配那条。与其在各处手敲命令比对版本,不如用 DSH Plugin Hub 这类可视化插件市场:已安装列表带版本号与来源标记、装卸历史与系统日志集中在一个面板里,先确认「环境里各组件都是什么版本」。

来源:Discussion #9640、Discussion #9346、Discussion #9552、Discussion #8849。
常见问题
在 DeepSeek Harness 里,这条报错信息太薄,是因为诊断信息在投影时被折叠掉了。适配器会把几种不同的底层错误一并折叠成 product-error,真实的错误标识在这一步被丢弃;而诊断渲染又只输出固定字段,完整原因虽然保存在失败实例上,却没有任何地方去读它。可行的做法是用抓取 app-server 通信的社区插件把真实的错误标识捞出来,再按标识去查上游含义。
在 DeepSeek Harness 里,典型原因是宿主内置的 Codex 二进制版本比你本地配置的模型更旧。子代理会沿用本机 Codex 配置文件(例如默认模型写在新版本才支持的模型名上),旧运行时读不懂这个模型,就会在启动或首轮失败。判据是看宿主解析到的可执行路径与它的版本号,以及解析后实际使用的模型名,四件事(可执行路径、版本、CODEX_HOME、模型名)对齐后问题通常一目了然。
在 DeepSeek Harness 里,删目录清不掉条目是因为子代理记录已改成「写在父会话日志里的目录事件 + 一个投影」,而这条记录是只追加的。删除目录不会产生「退役」这类事件,事件、投影、查询与工具四层都没有移除路径,界面上自然清不掉。目前没有可用的用户侧规避,插件也做不到,因为折叠逻辑会忽略其它事件类型。
在 DeepSeek Harness 里,这是因为子代理结算阶段读收件箱时缺了异常防护:当收件箱状态取不到值时读取函数会直接抛出,而调用它的结算逻辑是一个没有捕获的异步立即执行函数,于是异常逃逸成未处理拒绝,把整个进程带崩。特征是时间上大约十几分钟必现、崩溃栈能映射到收件箱读取与结算激活两处源码。
在 DeepSeek Harness 里,回退到不启用 continuation 与 activation 机制的旧版本可以绕开,因为问题出在这条结算链路上;如果不能回退,就要接受「进程会自己退出」并靠外部守护重启。注意这不改变根因,只是把不可用变成可恢复。
相关术语
- subagent_codex
- subagent_codex 是 DeepSeek Harness 里把 Codex 作为子代理后端的实现,它通过 Codex 的 app-server 协议通信,并把失败归类为若干产品级类别。分类折叠过度会导致细节丢失,是「只报 product-error」的直接原因。— https://github.com/deepseek-ai/deepseek-harness/discussions/9640
- subagent/catalog 事件
- subagent/catalog 是 DeepSeek Harness 写在父会话日志里、记录子代理目录的事件类型,配合 subagentCatalog 投影供界面展示。它是只追加的记录,当前没有对应的退役或移除事件,因此删除磁盘目录不会让界面条目消失。— https://github.com/deepseek-ai/deepseek-harness/discussions/9552
- continuable subagent
- continuable subagent 是 DeepSeek Harness 里一种可继续的子代理形态,父代理在它结算阶段会读取收件箱以接收结果。这条结算路径缺少异常兜底,是「子代理拖垮整个进程」发生的链路。— https://github.com/deepseek-ai/deepseek-harness/discussions/8849
- stage: turn
- stage: turn 是子代理失败信息里的阶段字段,表示失败发生在「本轮执行」阶段而非启动阶段。它能缩小排查范围,但由于同一阶段被折叠了多种底层错误,单靠它不足以定位到具体原因。— https://github.com/deepseek-ai/deepseek-harness/discussions/9640
来源
- #9640 — subagent_codex 连续失败只返回 Product subagent failure(stage: turn / category: product-error),无任何底层详情· deepseek-ai(GitHub Discussions)
- #9346 — Codex subagent can fail when DSH's bundled Codex is older than the user's configured model· deepseek-ai(GitHub Discussions)
- #9552 — 回归:0.2.0-rc.2 起,删除子代理会话目录不再从 UI 清除该条目· deepseek-ai(GitHub Discussions)
- #8849 — 子代理结算时 projection registration 失效会让整个进程致命退出(fatal load failure / exit 1)· deepseek-ai(GitHub Discussions)