DeepSeek Harness 会话显示异常:标题不生成、只跑命令显示空白与删缓存丢会话

故障排查发布于 2026-10-17作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSH 会话New Sessionsession_projcache会话标题maxOutputTokens侧边栏空白
DeepSeek Harness 里三种「会话看起来不对」的形态:只跑过命令的会话被当成空白会话、视图与标题全隐藏;删掉 session_projcache 后侧边栏报「暂无会话」;自动标题始终停在截断首句。本文给出各自的源码级判据、一行级修法与恢复步骤。

DeepSeek Harness(DSH)里有一类问题不报错、不崩溃,只是「看起来不对」:一个只跑过命令的会话打开是欢迎页、视图标签全不见、标题写死成 New Session;清理磁盘时删掉投影缓存之后,侧边栏直接报「暂无会话」,让人以为历史全丢了;开了自动标题之后,标题永远停在首句被截断的样子,日志里只有一条 warn。 三种现象在本批讨论里各自有明确的源码级判据:第一种是判空条件漏了 command/run(只认 turn/start),于是「只跑过命令」的会话被一直当成空会话,而且这个标记会门控四个下游消费者;第二种是文档说 session_projcache 非权威、实现却拿它当列表来源,缓存缺失时列表为空且不重建;第三种是标题 provider 的输出上限被配成 64,而思考链会把这点 token 吃光,于是每次标题生成都以 length 结束、内容为空,失败只写进 warn(#9380、#9611、#9661)。本文按「误判为空 → 列表依赖缓存 → 标题静默失败」逐个给出判据与处置。

DeepSeek Harness 只跑过命令的会话被当成空白:标题与视图全隐藏

一句话结论:判空条件只认 turn/start、不认 command/run,所以「跑过命令但没聊过天」的会话会一直被当成空会话,显示欢迎页、隐藏对话与轨迹视图,并忽略你 rename 过的标题。 更麻烦的是它带来一个更重的后果:这种会话会被当成「可复用的空会话」(#9380)。

据社区逐条核对源码,链路是这样的:

  1. 客户端在 session-controller 的列表逻辑里计算 blank 标记,清零条件只有 turn/start 一种事件;
  2. 只跑过命令的会话(command/run)不会触发清零,blank 保持为真;
  3. 下游四个消费者全部被这个标记门控:DefaultConversationViews.tsx(默认视图)、ConversationMainPanel.tsx(主面板)、Rows.tsx(列表行)、snapshot.ts(快照);
  4. 于是表现成「欢迎页 + 隐藏视图 + 标题显示为 New Session + 忽略重命名」(#9380)。

DSH插件 三步确认:是误判而不是真的空

  1. 看界面现象组合:打开的会话显示欢迎页、Chat / Trajectory / 插件视图标签消失、标题为 New Session(哪怕你改过名)——三者同时出现即高度可疑(#9380)。
  2. 看会话文件里的事件类型。在会话存储目录(~/.dsh/storages/sessions/)里找到该会话文件,检查事件类型分布:
powershell
Select-String -Path "<会话文件>" -Pattern '"type":"(turn/start|command/run)"' -AllMatches |
  ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value } |
  Group-Object | Select-Object Count, Name
#   预期:看到 command/run 有若干条,而 turn/start 为 0

「有 command/run、无 turn/start」就是本条的指纹(#9380)。

  1. 做对照:同一个会话里发一条普通消息(产生 turn/start),预期视图与标题立刻恢复正常——这条对照能立刻区分「误判」与「真的空」(#9380)。

DeepSeek Harness 处置:一行级修法 + 两个临时办法

修法本身只有一行——让判空同时排除 command/run:

blank = state.blank && event.type !== 'turn/start' && event.type !== 'command/run'

只加 command/run 就够,客户端不需要跟着改(#9380)。用户侧没有源码可改时,两个临时办法:

  1. 发一条消息把 turn/start 带出来,视图与标题立即恢复;缺点是这个会话不再「干净」。
  2. 换用插件命令装出的会话做验证:如果某类插件习惯用命令启动会话,就更容易长期踩中——把这类会话当成「需要补一条对话才能正常显示」的已知限制处理。
  3. 重命名后再观察:session.rename 写的标题本身是生效的,只是被 blank 门控挡住了,所以「改名无效」也是同一个根因(#9380)。

DSH插件 删掉投影缓存后侧边栏报「暂无会话」:列表依赖了被称作非权威的缓存

一句话结论:session_projcache 被文档描述成「非权威缓存」,但当前实现里会话列表确实从它构建,所以删掉它就会看到「暂无会话」——会话数据还在,只是列表不再从权威来源重建。 讨论中的实测是:删掉或移走该目录后,侧边栏显示 No sessions yet、工作区列表空白,而会话文件都还在(#9611)。

DeepSeek Harness 三步恢复:先别再删,再查文件,最后重建

  1. 先确认会话文件还在(这是最要紧的一步):
powershell
Get-ChildItem "$env:USERPROFILE\.dsh\storages\sessions" |
  Sort-Object LastWriteTime -Descending | Select-Object -First 10 Name, Length, LastWriteTime
#   预期:能看到近期会话文件与合理体积(几百 KB 到数 MB)

只要这里有文件,就说明数据没丢,属于列表展示问题(#9611)。

  1. 把缓存目录移回原位。如果只是「移走」而不是删除,直接移回即可;如果已经删除且在回收站,先恢复。注意:以后要清就「移走」,不要直接删——移走可回滚,删除要重建(#9611)。
  2. 让它重建。重启 DSH 后观察侧边栏是否恢复;据讨论中的分析,当前实现不会在后台自动重建这份缓存,因此更稳的做法是保留一份缓存备份,或者接受「列表与标题预览需要重新生成」的等待(#9611)。
  3. 想彻底避免这类风险:把 ~/.dsh 纳入常规备份,尤其别把「清理临时/缓存目录」的脚本无差别指向它——讨论里提到的那种「外部批量清理把运行时目录一起干掉」的事故,往往就是从这里开始的(#9611)。

一个来自讨论的证据值得记下来:有用户指出列表本可以只读每个会话的第一条 zstd 帧头就够(拿标题与时间),也就是说「列表必须依赖全量投影缓存」这件事在实现上并非不可替代——这正是修复方向:列表从会话存储/头部构建,缓存只用于补标题与预览(#9611)。

DSH插件 自动标题不生成:64 个 token 被思考链吃掉

一句话结论:标题 provider 的输出上限被配成 64,而推理型路由的思考 token 也计入 max_tokens,于是 64 个 token 在标题正文还没产出时就被耗尽,返回 finish_reason: length 且内容为空,最终抛 maxOutputTokens 超限——失败只写一条 logger.warn,界面上只表现为「标题一直不更新」。 症状是会话标题长期停在首句被截断的 fallback 形态(#9661)。

据报告者实测与另一位用户的修法建议:启用 @deepseek-ai/dsh-experimental-session-titles-bundle 之后,该 bundle 的 cordis.patch.yml 给 all-prompts 的标题 provider 配了 maxOutputTokens: 64;而 provider 会选用路由上的最低推理档,推理型路由的 compat.thinkingFormat: deepseek 会把思考 token 计进 max_tokens,于是预算被思考吃光(#9661)。

DeepSeek Harness 四步确认与修复

  1. 确认症状组合:会话标题为「首句截断」形态、且长期不变;新建会话也一样;而会话内容本身完全正常。
  2. 看日志里的 warn。预期在宿主日志里能搜到标题生成失败相关的 warn:
powershell
Select-String -Path "<DSH 日志文件>" -Pattern "title output reached maxOutputTokens"
#   预期:命中若干条
  1. 在 profile patch 里按 id 覆盖 maxOutputTokens,把它抬到一个合理值(例如 4096)。要点是这类覆盖是浅替换,需要重述该 provider 行的其它字段,别只写一项(#9661):
yaml
# 在 profile 的 cordis.patch.yml 里按 id 覆盖标题 provider
- patch:
    id: <标题 provider 的 id>
    config:
      maxOutputTokens: 4096
      # 其余原有字段需一并复述,浅替换不会保留未写的键
  1. 验证:重启后新建一个会话并发一条消息,预期几秒内出现自动生成的标题而不是截断首句;再确认日志里不再出现那条 warn。
  2. 替代做法:把标题生成切到非推理模型,或直接不使用该实验 bundle——如果不需要自动标题,这类静默失败的排查成本就消失了(#9661)。

DSH插件 排查注意事项

三条都属「界面表现与数据实况不一致」,共同的第一原则是:先确认数据在不在,再怀疑界面。 七条要点:

  1. 空不空看事件,不看界面:有 command/run 无 turn/start 就是误判,不是真的空;反过来,会话打不开、或日志里带着像 reason:null 这类非法字段的,是写读不一致的另一族,见 DeepSeek Harness 会话打不开(#9380)。
  2. 「改名无效」和「显示新会话」是同一个根因,别当成两个 bug 分别查(#9380)。
  3. 误判成空还有一层风险:这类会话会被当成「可复用的空会话」,所以它不只是显示问题(#9380)。
  4. session_projcache 要「移走」不要「删除」:移走可回滚,删除后当前实现不会自动重建(#9611)。
  5. 清理脚本别无差别指向 ~/.dsh:这份目录里同时装着会话、存储与运行时状态,删缓存顺手删掉它们是常见事故(#9611)。
  6. 标题不更新先看 max_tokens 与推理档的关系:推理 token 计入输出上限,这是本族的核心机制(#9661)。
  7. 修复状态如实:判空条件、列表依赖缓存、以及标题 provider 的默认 maxOutputTokens 在讨论所指版本里都仍是现状;标题那条可通过 profile 覆盖在用户侧解决,前两条属核心侧改动。

排查这类「列表与标题」的问题时,很容易怀疑是插件把界面搞坏了。如果你想先把插件变量排掉,与其在各处手敲命令,不如用 DSH Plugin Hub 这类可视化插件市场——已安装列表、装卸历史与系统日志都在一个面板里,确认「当前装了什么、最近动过什么」会快一些。

已安装插件列表

来源:Discussion #9380、Discussion #9611、Discussion #9661。

常见问题

DeepSeek Harness 里一个会话只跑过命令、没聊过天,打开却是欢迎页,Chat 与 Trajectory 标签都不见了,标题还显示 New Session,怎么找回?

DeepSeek Harness 里只跑过命令的会话打开是欢迎页、标签全消失、标题显示 New Session,是会话被错误判定为 blank 造成的。据社区核对源码,判空条件只认 turn/start 事件,不认 command/run,因此「只跑过命令」的会话会被一直当作空白会话,下游的默认视图、主面板、行渲染与快照四处都被这个判定门控,标题也会被强制显示为新会话、忽略你 rename 过的名字。修法是让判空同时排除 command/run,即 blank = state.blank && event.type !== 'turn/start' && event.type !== 'command/run';临时可用新建一个会话、发一条消息把 turn/start 带出来恢复显示。

清理磁盘时删掉了 ~/.dsh/storages/session_projcache,结果 DeepSeek Harness 侧边栏显示 No sessions yet,会话是不是被删了?

删掉 session_projcache 后 DeepSeek Harness 侧边栏显示 No sessions yet,会话并没有被删,是列表依赖了这份投影缓存。文档把 session_projcache 描述为非权威缓存,但当前实现的会话列表确实从它构建,缓存缺失时列表为空且不会自动重建。恢复办法是先把缓存目录移回原位(如果还在回收站或备份里),或直接从会话存储重新生成;判定会话文件是否还在,可以直接看 ~/.dsh/storages/sessions 目录下的文件数量与修改时间。

为什么 DeepSeek Harness 自动生成的会话标题一直停在第一句话被截断的样子,日志里只有一条 warn?

DeepSeek Harness 的自动标题一直停在截断首句、日志里只有一条 warn,是因为标题生成的输出上限被配成了 64,而这些 token 会被思考链吃光。启用 session-titles-bundle 后,标题 provider 会选用路由的最低推理档,推理型路由的 thinking tokens 也计入 max_tokens,于是 64 个 token 在还没产出标题正文时就用完,返回 finish_reason: length 且内容为空,最终抛 maxOutputTokens 超限。修法是在 profile patch 里按 id 覆盖该 provider 的 maxOutputTokens,抬到 4096 之类的合理值。

怎么判断一个 DeepSeek Harness 会话是「真的空」还是「被误判成空」?

判断一个 DeepSeek Harness 会话是「真的空」还是「被误判成空」,看会话里有没有事件,而不是看界面。在会话存储目录里找到对应文件,检查它是否包含除会话头之外的事件:如果只有 command/run 而没有 turn/start,就是被误判成空白的这一族;如果文件本身只有几十字节或干脆不存在,那才是真的空会话。界面上的欢迎页与 New Session 标题不构成判据。

相关术语

blank 会话
blank 会话是 DeepSeek Harness 客户端对「尚未开始对话」的会话的内部标记,命中后会显示欢迎页、隐藏对话与轨迹视图、并把标题强制渲染为 New Session。它当前只依据 turn/start 事件清零,因此只跑过命令的会话会被一直保留在这个状态。— https://github.com/deepseek-ai/deepseek-harness/discussions/9380
session_projcache
session_projcache 是 DeepSeek Harness 存放在 ~/.dsh/storages 下的会话投影缓存目录,用于加速侧边栏列表与标题预览的读取。文档称它为非权威缓存,但当前实现的列表构建依赖它,缺失时不会自动重建。— https://github.com/deepseek-ai/deepseek-harness/discussions/9611
maxOutputTokens
maxOutputTokens 是单次模型调用的输出上限,指模型返回内容的最大 token 数。在推理型路由上,思考链产生的 token 通常也计入这个上限,因此把上限设得过低会导致正文还没开始就被截断。— https://github.com/deepseek-ai/deepseek-harness/discussions/9661
fallback 标题
fallback 标题指自动标题生成失败时退回使用的兜底标题,通常取会话首句并做截断。它不携带失败原因,因此当标题生成静默失败时,界面只会显示这个截断首句而不提示任何错误。— https://github.com/deepseek-ai/deepseek-harness/discussions/9661

来源