DeepSeek Harness 报 sessionProjections inactive context 工具全挂
跑到一半突然报 cannot get required service "sessionProjections" in inactive context,之后这个会话里每个工具调用都失败,换工具、换模型都没用;新建一个会话,一切正常。 这是 DeepSeek Harness(DSH)里典型的上下文生命周期问题:报错方拿着一个已经卸载的 Cordis fiber 的 ctx 去读服务,服务其实还在,只是这个入口失效了(来源)。
先确认:DeepSeek Harness 报的是上下文失效不是权限错误
只有报错文本里同时出现 sessionProjections 和 inactive context,才按本文处理;权限问题看 403,模型问题看 provider 与 400。
- 读报错原文,确认服务名与 inactive context 同时存在。预期:两者都在,且没有状态码。
- 在同一会话里换一个无关工具,例如
bash、文件读取、搜索。预期:以同样方式失败。 - 新建一个会话,跑同一个工具。预期:正常返回,说明工具本身没坏。
- 重启 host 后打开旧会话再试。预期:可能短暂恢复,随后再次失败。
- 检查最近是否重载或停用过插件。预期:时间点和第一次报错对得上。
| 判据 | 本文故障 | 权限问题 | 模型问题 |
|---|---|---|---|
| 报错文本 | 含 inactive context | 403 / preset | provider / 400 |
| 新会话 | 正常 | 同样失败 | 同样失败 |
| 换工具 | 一律失败 | 视权限而定 | 视模型而定 |
据讨论里的源码核对,vendor/cordis/src/reflect.ts:136-171 的 get trap 在 :163 继续上溯之前,先命中 prop in fiber.inject 就抛错;所以报错含义是「读的是已卸载 fiber 的 context」,而不是「进程没有这个服务」(#10272)。
根因:DeepSeek Harness 会话为什么握着已卸载的 ctx
会话在某个 fiber 存活时缓存了 ctx,fiber 卸载后引用没有更新,后续工具调用继续用旧 ctx。
- 某个 DSH插件 或会话在某次初始化时拿到
ctx并保存。预期:引用挂在长生命周期对象上。 - 该插件被热重载、禁用,或因错误卸载。预期:fiber 变为不活跃。
- 会话对象仍持有旧 ctx,没有任何代码清理它。预期:引用继续有效(表面上看)。
- 下一次工具调用通过旧 ctx 读
sessionProjections。预期:进入 get trap。 - trap 发现该 fiber 的 inject 包含该服务,但 fiber 已不活跃。预期:抛错。
- 会话继续复用旧 ctx。预期:每次调用都在同一处失败。
热重载、频繁启停插件、长时间运行都会提高触发概率。注意这不是服务缺失,重启 host 能好也正说明服务本身是健康的。
判断上还有一点容易走偏:报错里的「inactive」修饰的是 context,不是服务。服务名出现在错误里,只是因为它恰好是这次读取的目标。
修法一:把工作迁到新的 DeepSeek Harness 会话
最快恢复,适合当前会话价值不高、或者内容还能复制出来的情况。
- 把旧会话最近几轮的关键结论、文件路径、待办复制出来。预期:得到一份能直接粘贴的交接说明。
- 新建会话,粘贴背景,跑一次只读工具。预期:工具正常返回。
- 把重要的工具结果一并贴过去。预期:模型不用重复执行昂贵的工具。
- 归档旧会话。预期:不会误点进去继续失败。
- 在新会话里继续原任务。预期:上下文连续,工具可用。
- 观察十分钟。预期:没有回到同一个报错。
- 把旧会话标记为只读。预期:以后不会再往里追加失败记录。
这条路的代价是丢掉旧会话里的隐式上下文。长任务要先把结论写下来,别指望模型记得。
修法二:重启 DeepSeek Harness 让会话重新绑定
重启能清掉旧 fiber 和 ctx,部分会话会恢复;如果重启后仍报错,说明坏引用被持久化了,只能迁移。
- 完全退出 DSH,确认进程结束。预期:没有残留 host 进程。
- 重新启动,打开报错会话。预期:会话能加载。
- 先发一条纯文本消息,再触发一次工具调用。预期:工具调用完成。
- 如果恢复,继续使用;如果同一位置再次报错,转修法一。预期:不用反复重启。
- 记录触发前做了什么操作。预期:能判断是否与热重载有关。
- 再连续调用两个工具。预期:没有延迟复发。
- 查看启动日志里的 fiber 初始化顺序。预期:没有插件加载失败。
重启只重建一次运行状态。如果你装了会频繁重载的插件,失败很可能在下次重载后回来。
修法三:改 DeepSeek Harness 调用点,不再缓存 ctx
根治方向是不要在会话对象里长期保存 ctx,或在 fiber 卸载时清理引用;读取服务时用当前活跃的 context。
- 搜索会话管理中缓存
ctx的字段,确认生命周期。预期:找到一处明确的缓存点。 - 在 fiber 的
dispose钩子里清空该引用,或改成惰性获取。预期:卸载时引用消失。 - 对
sessionProjections的读取,改成从当前活跃会话的 context 取。预期:每次读取都经过活 fiber。 - 给 get trap 的报错补上 fiber id 与卸载原因。预期:下次报告能直接点名死掉的 fiber。
- 补测试:卸载 fiber 后继续调用工具。预期:复用死 ctx 时测试失败。
- 在 PR 里说明复现路径。预期:维护者能核对 0.2.1-rc.2 的行为。
惰性获取会带来一次额外查找,但比拿着一份随时可能失效的引用安全。读多写少的路径优先改成惰性。
验证与边界:DeepSeek Harness 插件重载后复查
修复完成的标准是工具能扛过一次插件重载和一次 host 重启,而不只是下一条调用能过。
- 在修复后的会话里连续调用三种不同工具。预期:都不再报 inactive context。
- 触发一次插件重载,再调用工具。预期:ctx 引用已刷新,调用成功。
- 重启 host,重新打开会话。预期:仍然可用。
- 新建会话做对照。预期:没有引入新的服务缺失。
- 观察一小时内的工具失败率。预期:没有同一位置的重复报错。
- 检查会话日志能否正常追加。预期:工具结果没有断档。
如果只有部分工具失败,先按工具类型分组再看;同一会话里出现两种报错时,别把两条链路混成一条。
边界有四条:不要把这个错误当成 sessionProjections 服务坏了;重启不一定能救回原会话;热重载是高风险操作,长任务中途尽量别启停插件;同一会话内切换模型不会重建 ctx。讨论里没有官方修复版本,0.2.1-rc.2 仍可复现,相关的构造期死锁见 权限预设 auto 死锁。
常见问题
DeepSeek Harness 的报错说明该会话持有的 context 来自已卸载的 Cordis fiber,后续每次工具调用都复用它。新建会话会创建新的 fiber 和 context,所以绕过问题;原会话不会自愈。
这是 DeepSeek Harness 的读取方式问题。sessionProjections 仍由活跃 fiber 提供,但报错方持有已卸载 fiber 的 ctx,get trap 先命中该 fiber 的 inject 列表就抛错。服务本身没有坏。
DeepSeek Harness 的这个错误会在文本里同时出现服务名和 inactive context。权限问题通常是 403 或 preset 报错,模型问题会带 provider 或 400,与网络和密钥无关。
DeepSeek Harness 用户侧没有直接修复入口。可行的做法是把消息导出到新会话,或重启 host 后重新打开,让它重新绑定 context;重启仍失败就说明坏引用被持久化了。
相关术语
- sessionProjections
- sessionProjections 是 DeepSeek Harness 按会话维护的派生服务集合,permissions、usage 等投影都挂在它下面。它由活跃 fiber 发布,读取时必须使用该 fiber 的 context。— https://github.com/deepseek-ai/deepseek-harness/discussions/10272
- inactive context
- inactive context 是一个已经卸载的 Cordis fiber 的上下文对象。通过它读取服务会抛错,因为该 fiber 的服务注册已经失效。— https://github.com/deepseek-ai/deepseek-harness/discussions/10272
- fiber
- fiber 是 Cordis 的插件运行单元,负责注册服务、管理生命周期与依赖。fiber 卸载后,它持有的 context 不应再被业务代码使用。— https://github.com/deepseek-ai/deepseek-harness/discussions/10272
来源
- #10272 — 跑多个任务后报 cannot get required service sessionProjections in inactive context· deepseek-ai(GitHub Discussions)
- DeepSeek Harness 官方仓库· deepseek-ai(GitHub)