You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
环境
DSH Desktop:2.0.10
@deepseek-ai/dsh:0.1.5-rc.2
Provider:deepseek-official
系统:Windows 10/11(PowerShell 5.1)
涉及会话:session-05bed7f7-…(父)、session-4ca16fff-…(其 Side chat 子会话)
现象
一个正常进行到第 5 轮的会话,在一次网页抓取之后突然再也无法继续。
之后每一条用户消息(哪怕只发一个「?」)都在约 1 秒内失败
轨迹页只显示一行:本轮运行失败 · Content Exists Risk(INVALID_REQUEST / HTTP 400)
切换模型无效(换成其它模型是同样的报错)
重启应用、重开会话均无效
会话本身没坏:能打开、能看历史、能滚动,只是不能产生任何新回合
结果:这个会话彻底报废,连带它开出的 Side chat 子会话一起报废(子会话是父会话的种子副本,继承了同一份历史)。
关键点:这个失败是粘性的,且没有任何出路
失败发生在「把新工具结果纳入请求」的那一步。触发源进入历史后再也不会离开,因为每轮请求都会重新上传整段历史。
复制
第 5 轮第 4 步 工具结果进入历史 成功
第 5 轮第 5 步 首次包含该结果的请求 失败 400 Content Exists Risk
第 6、7、8 步… 用户重试 失败(历史里仍带着它)
换模型没用,重启没用,发新消息没用。 应用里没有任何「删除 / 截断 / 编辑某条消息或工具结果」的入口,也没有「从某轮之后重新开始」的恢复流程。用户唯一的办法是放弃这个会话。
对普通用户来说,这就是「聊到一半,对话突然死了,且无法解释」。
触发源定位
起因是一次网页抓取,触发源是该页的正文:
复制
seq 347 tool/call web_fetch
https://blog.yeyupiaoling.cn/article/1787814220553
seq 353 tool/result 该页正文(6525 字符)
seq 356 assistant/attempt 失败 Content Exists Risk
独立复现:另一个与此会话没有历史传递关系的会话(session-b54013ef-…),在把同一篇网页正文读入上下文后,同样立刻开始持续 400。两个会话唯一的共同点就是这篇正文。
已排除的其它解释(均为实测):
孤立 UTF-16 代理码元(见 Discussion #436):逐码元扫描,0 个
JSON 转义代理码元 / U+FFFD / 不可见字符 / 双向覆盖:全为 0
上下文体积超限:另一会话仅 39 万字符即失败,不存在固定阈值
关键词级敏感词(政治、色情、赌博等 40 多个词):未命中
提示词注入特征:0 处
另外有一点值得说明:该页的标题与小节标题是无害的,有毒的是正文。 我自己的诊断会话里一直带着那些标题,请求全部正常。所以问题不在「抓了这个域名」,而在「把这段正文灌进了历史」。
失败事件的日志原文(已折行,便于阅读):
复制
type: assistant/attempt
seq: 356 turn: 5 step: 5
reason:
kind: error
failure:
message: Content Exists Risk
code: INVALID_REQUEST
status: 400
另外:Side chat 子会话显示「会话记录损坏」
session-4ca16fff-… 是父会话开出的 Side chat(provider 为 sidechat,isSeeded 为 true)。它的日志是从父会话整段复制的,因此同样带着污染内容。它的日志终止于 session/end-seed 和 session/title,从未产出过自己的回合,在会话列表里被标为**「会话记录损坏」**。
这个提示对用户很有误导性:它让人以为是数据坏了,实际上是内容被风控拒绝。
建议
按我认为的价值排序。
这是最核心的一条。至少要有一种出路,以下任选其一:
允许用户删除或截断某条消息、某个工具结果,或「从第 N 轮重新开始」
提供一个**「恢复会话」**流程:自动逐步丢弃尾部可疑内容,直到请求能通过
在写入历史前对工具结果做一次可配置的体检(超长、来自外部的网页正文等)
2. 区分错误类型并给出可操作提示
Content Exists Risk 目前只在轨迹页显示一行「本轮运行失败」。建议在识别为内容 / 风控类拒绝时,明确提示「本会话历史被服务端拒绝,需清理历史或新建会话」,并指向可用的恢复入口。
给网页抓取提供一个「只取摘要或限长」的模式
很多场景(比如查一个插件的用法)根本不需要把整页正文灌进历史。若能限制注入长度或只取正文摘要,可以显著缩小这类风险面。
文档补一句
「服务端内容风控拒绝会永久污染会话历史,且不会自愈」—— 这一条现在只能靠用户自己踩出来。
附:临时自救办法(给其它遇到的人)
会话日志是多个独立 zstd 帧拼接的 JSONL,且一行 JSON 可能跨帧。在应用关闭状态下操作:
备份 session.v3.jsonl.zstd(位于 ~/.dsh/sessions/ 下的会话目录)

用官方 zstd CLI 解压。必须让 zstd 自己写文件,不要用 PowerShell 的 > 重定向,否则会写成 UTF-16LE:
复制
zstd.exe -d -f -q -o out.jsonl session.v3.jsonl.zstd
找到含触发内容的帧,只重写受影响的帧(每帧恰好占 [starts[k], starts[k+1]),其余帧可保留原始字节),把那段文本替换成占位说明,事件结构与 seq 保持不变
用 zstd 压回拼接帧格式,替换原文件,重启应用
注意:Node 的 zstdDecompressSync 只解第一帧,createZstdDecompress 流会在第二帧报 Unknown frame descriptor,都不能用。
All reactions