Repository navigation
会话引用 URI 解析失败会让整轮直接失败(含复现,触之必死且会自我扩散) #9613
Replies: 1 comment
|
A plugin-form mitigation for this is on npm —
It is an independent Cordis package with a - insert:
- id: session-reference-guard
name: '@argszero/dsh-session-reference-guard'What it doesIt registers the same Why the predicate has to be asked rather than mirroredYour report's own table is the reason, and it is worth spelling out because it also bears on the fix you propose. The refusals come from two different places in the same decoder:
A heuristic on length or charset cannot separate either of those from a working reference, which is why the plugin does not use one. Your more conservative suggestion — only treat it as a reference when the payload is in canonical form — is the right rule, and "canonical" here is exactly " Applying your log suggestion to the guard's own diagnosticYou wrote that the log should not print the URI verbatim, so the log does not become a second source of contamination. That point landed on this plugin too. It reads the same, and it cannot be pasted back into a literal. I kept the literal in the line rather than dropping it for a code plus payload length, because the whole use of the diagnostic is "which text do I need to go and fix" — but the escape gives that without the hazard. Scope, honestlyThis is repair at the step boundary, not a fix of the condition. The throw is still there, and a guard cannot make the parser accept a literal it refuses. The real fix is the fail-open you describe — a Evidence56 tests across 5 suites: the real waterfall through Two modes besides the default |
Uh oh!
There was an error while loading. Please reload this page.
问题:
当一条用户消息的文本里出现“会话引用 scheme 紧跟一小串数字”这种字面量(本例中为dsh-session:382)时,agent/pre-step 阶段的解析器会抛错,导致整轮运行直接失败。前端只显示“本轮运行失败 / UNKNOWN invalid session reference URI "dsh-session:382": Unexpected token '�', "��" is not valid JSON
”,用户无法继续往下走;更麻烦的是,他试图把报错原文贴出来求助时,同样失败——错误文本本身也包含触发它的字面量。
复现
发送一条内容为:dsh-session:382
也就是 scheme 后面跟三位数字(注意这不是合法的 base64url payload)。任何包含该字面量的文本都会触发,不管它出现在一整句里、任务行里还是 markdown 里。
现象
前端:本轮运行失败,code UNKNOWN
后端报错原文:invalid session reference URI "dsh-session:382": Unexpected token '�', "��" is not valid JSON
根因(包 @deepseek-ai/dsh-session-reference)
lib/index.js:467-474 SessionReferenceResolver 挂在 agent/pre-step(prepend)
lib/index.js:484-490 prepareDirectMessages() 对每条 user 消息的每个 text 块调用 parseSessionReferenceText,调用点没有 try/catch
lib/index.js:320-337 正则的裸文本分支匹配“scheme + [A-Za-z0-9_-]+”
lib/index.js:290-303 payload 通过 /^[A-Za-z0-9_-]+$/(纯数字也合法),随后做 base64url 解码再 JSON.parse
lib/index.js:344-346 失败即 invalidUri() 抛出 SESSION_REFERENCE_INVALID_REFERENCE
三位数字解码出 2 个非法 UTF-8 字节,正是报错里那个替换字符的来源。因为抛出发生在 pre-step 里,所以整个回合直接失败。lib/types/uri.js 里有同一份逻辑拷贝。
影响范围(我们实测)
在 0.1.5-rc.3、0.1.7-rc.2、0.2.0-rc.2、0.2.1-alpha.2 四个版本上,lib/types/uri.js 逐字节相同,解析逻辑一行未改,四个版本都抛同样的错。上游 master 的 packages/context/session-reference/src/uri.ts 同样是 throw,也没有修复。
实际影响不止“某条消息发不出去”:我们这边的自动化代理只要读到包含该字面量的文件(日志、任务清单、报告、测试夹具),同样当场死亡;连续多个代理被同一个字符串杀掉,排查成本极高。因此我们把它称为“触之必死且会自我扩散”——触发它的文本,恰恰是出错后最需要被复制传播的那段报错。
建议
最小改动是 fail-open:解析失败时不要抛出,把这段文本当作普通文本继续处理,并记一条日志;日志里不要打印 URI 原文,只记错误码与 payload 长度,避免日志本身变成二次污染源。
我们没有采用“按长度或字符集启发式判断像不像合法引用”的做法:短 payload 也可能确实是合法引用,启发式会误杀正常功能。另一种更保守的思路是,只在 payload 满足 canonical 形态(例如足够长、且能解出合法 JSON)时才视为引用,其余一律按普通文本处理。
参考
同模块既有问题:8030
同族先例:8352(未配对的 UTF-16 代理项,导致会话永久 HTTP 400)、9544
环境
Windows,桌面端 Deepseek Harness EAC 5.3.6,内核 @deepseek-ai/dsh 0.1.5-rc.3
All reactions