Repository navigation
Inbox: same pending message canceled + re-inserted after an error turn (429) - duplicate agent/inbox/spliced inserts #9482
Replies: 1 comment 1 reply
|
Answering both from the shipped tree, because the pair is not a recovery semantic — the loop never puts cancelled input back. Where Nothing in core re-inserts a discarded message. All three listeners on That leaves the producer. The only way one For the scanner, the rule that holds today: On residency (2): there is no upper bound, by design. |
Uh oh!
There was an error while loading. Please reload this page.
Context
While auditing plugin-delivered steering messages in session logs (we run a duplicate-alert scanner over
agent/inbox/splicedevents), we observed an event-level duplication pattern that looks unintentional. Sharing in case it is known/desired behavior; two questions at the end.Observation
A message inserted into the
next-turnpending list during a turn that later ends with an LLM error (429 quota) gets canceled and immediately re-inserted at the same position when the next turn starts — producing twoagent/inbox/splicedinsert events for the same message id (161 ms apart, no net state change).Timeline (UTC+8, 2026-10-01, session log excerpt; message ids abbreviated):
agent/inbox/splicedb286-…77229@ next-turn[1]turn/endagent/inbox/splicedagent/inbox/splicedb286-…77229@ next-turn[1] (same id, same position)agent/inbox/spliceduser/messageSo the model only sees the message once (claim → enter happens exactly once); the duplication lives at the event-stream level, which matters for consumers that replay or audit
agent/inbox/spliced(alert-redelivery scanners, projections, log-validation tooling).Source anchors (shipped tree)
dsh-agent-loopReactLoopInbox.claim()removes the full next-step batch (mutate("next-step", 0, len, [], false)) — claiming does drain; this is not a "queue never drains" report.mutate()only setsoutcome:"canceled"on the publicsplice()path (discardRemoved=true); claims carry no outcome.dsh-agenttracksdroppedUnrunwhenoutcome === "canceled"— so there appears to be a re-queue path for canceled-but-unrun input, which would explain the remove+reinsert pair above.Related prior reports on inbox splice stream oddities (different faces, same area): #3632 (orphan spliced splits vs session readability), #4274 (splice sequence conflicts on recovery), #4952 (queued follow-ups never admitted after turn end).
Questions
outcome:"requeued") so event-stream consumers do not count it as two deliveries?next-turnmessages can stay resident across several turns in our logs (4 turns / ~33 s in the sample above) before being claimed. Is there an intended upper bound or cleanup semantic for pending residency?Happy to provide the full session excerpt if useful.
All reactions