Bug: dsh-agent-loop auto-continue notice messages lack message.id, corrupting session history #4819
Replies: 3 comments
|
The missing identity is a real durable-boundary problem, but two source distinctions matter before fixing it. First, I cannot find either agent.inject(createUserMessage({
content: [{ type: 'text', text }],
source: { kind: 'plugin', plugin: 'the-producer', form: 'notice' },
}))
Second, there is a core fail-late gap that explains how such a message can persist. rc.2 I would fix both edges:
I would not make restore silently skip notice-form messages. Identity correlates queue edits, claims, surface projection, and replay. Likewise, adding a UUID only to the final There is also a separate physical boundary in the reported startup failure: I documented the exact source boundaries, evidence slice, safe quarantine route, correlated repair requirements, and regression gates here: |
|
这条报错( dsh-session-surgeon 现在会把这种文件标成 dsh plugin --profile web add "github:xiaoshenming/dsh-session-surgeon#main"这救的是已经落盘的坏日志。源头仍应让注入走 「一条坏会话拖垮整个 plugin tree」是 workspace |
|
Thanks @liyangbing for the detailed analysis — the fail-late gap explanation ( Direct evidence: the producer IS
|
Uh oh!
There was an error while loading. Please reload this page.
Bug Description
The
@deepseek-ai/dsh-agent-loopplugin, when auto-continuing after an empty reasoning-only response, injects auser/messagewithsource.kind = plugin,form = notice,summary = "auto-continue on empty reasoning-only response"and content like继续输出完整的分析与最终结论。(continue output). These synthetic messages are written to the session log without amessage.id(and withoutmessage.role/sourceon some paths).The session validator (
dsh-session,assertMessageEventShape) requiresuser/message/assistant/message/tool/resultevents to carry a non-emptymessage.id. A single missing id fails validation for the entire session, producing:Additionally, because
dsh-workspacescans all session logs at startup (listArtifacts->readFirstZstdLine), one corrupted session triggers the whole plugin tree load failure:Steps to Reproduce
We hit this twice in our environment (two different sessions, events at seq 2571 and seq 29082), confirming it reproduces on the same plugin notice path.
Expected Behavior
message.id(and properrole/source) like every other injected message.assertMessageEventShape) should not fail the entire session for a single malformed injected event; ideally skip/repair notice-form events or surface them as warnings.Actual Behavior
user/message(form=notice) is persisted; the session becomes unopenable; dsh-workspace fails to boot when scanning the corrupted log.Environment
@deepseek-ai/dsh-agent-loop0.1.1-rc.2)dsh webprofile through systemdWorkaround we used
The session log is a multi-frame zstd file. We split frames by the zstd magic bytes, decompressed only the frame containing the offending event, patched in a UUID for the missing
message.id, recompressed that single frame, and re-assembled the file. This preserves all events and passes validation. (Note: re-compressing the whole log as a single frame fails validation becauseassertZstdHeaderFramerequires the first frame to decompress to exactly one header line.)Suggested Fix
In
dsh-agent-loop, ensure the auto-continue notice message goes through the same message construction path as other injected messages (with id, role, source). Indsh-session, consider making the id requirement lenient forform: notice-type plugin events, or repair-on-read instead of fail-hard.Related: session-event validation code lives in
dsh-session/lib/types/index.js(assertMessageEventShape) and the log reader indsh-session-persistence-jsonl(assertZstdHeaderFrame).All reactions