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
[bug] Under heavy load new user requests no longer appear in the conversation/request view at all - history invisible (gap-repair strands user/message events)
#479
Bug report: under heavy load, NEW user requests no longer appear in the conversation / folded-request (Trajectory) view at all — the user's own history becomes invisible
Environment
DeepSeek Harness Web GUI (dsh web, 127.0.0.1:3080)
Following the earlier incident (input delayed by minutes under heavy concurrent load, ~20 parallel in-process subagents + dense web RPC), the situation has now escalated: from that point on, every new user request no longer shows up in the "collapsed requests" / request view at all. The user cannot see in the GUI what they previously entered — their own request history is effectively invisible.
This is not just delayed/queued; even requests that would later be processed do not render in the conversation or in the folded request (Trajectory) grouping.
What "collapsed requests" is here
The "collapsed / folded requests" content is produced by the conversation view (ui-conversation) and the Trajectory view (ui-trajectory), where each user request is rendered as a user cell inside a "Message"/Step N group that can be collapsed per turn/assistant (TrajectoryTable fold state: collapsedTurns / collapsedAssistants). The routing details:
packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts lines 66–111 — a user request becomes a kind:'user' node only from a durable user/message session event (event.type === 'user/message' with source.kind === 'user').
packages/client/ui-trajectory/src/client/layout.ts lines 354–366 — that user node is placed into the folded request layout as a kind:'user' cell (layout.tspushMessage).
The Chat view renders the same underlying node stream via the ordered node keys (ChatView.tsxorder.map(...) line 382).
TrajectoryTable.tsx lines 571–600, 628–660 — collapsed turns/assistants are hidden behind a summary row, but note line 583 still keeps requestOnly cells visible in a collapsed turn; so collapse state alone does not fully remove a request. The main cause of "not visible at all" is that the underlying user node is never produced.
Investigation — why a new request can fail to appear
The request is invisible while queued (shared with discussion [bug] User text input delayed by a long time under heavy concurrent load (queued behind a busy agent turn - no pending feedback) #477). A user request is queued into the agent inbox (agent.followup → nextTurn, core/agent-loop/src/agent.ts lines 122–123). The durable user/message event that the UI renders from is only appended by the loop when the busy turn finally runs that step (agent-loop/src/agent.ts line 283). While queued behind a busy turn, the message has no user/message event yet → no user node → nothing shows in Chat or the folded-request view.
When the event finally arrives but the client event-window has a seq gap under load, it can be stranded. The client session merges live session events through a contiguous event window with gap handling (packages/client/runtime/src/client/sessions/session.ts):
acceptLiveEvent (lines 684–697): if openState is 'loading'/'stitching', or the event's seq > tailSeq + 1 (a gap), the event (e.g. the user/message for the user's own request) is pushed into liveBuffer and a repairGap() tail-page repull is kicked off.
repairGap (lines 708–724): repulls session.history. If that RPC fails (result.ok === false), the generation went stale (a concurrent resync superseded it), or a transport error throws (caught and just console.error at lines 719–721), the gap is not repaired and the buffered event stays stranded in liveBuffer — it is never applied to the ConversationNodeAssembler, so the user request never renders.
installWindow (lines 646–665) is the only path that drains liveBuffer; without a successful tail repull there is no retry/timeout that clears it.
The dense-load enabler. All session events (tool chunks, user/message, turn boundaries) for all ~20 subagents stream over one per-tab mux downlink (packages/client/connection/src/websocket-downlink.ts serial pump, lines 118–137; browser buffer in packages/client/connection/src/client/web-api-client.ts). Under load a turn/start preceding the user's user/message can be missed/out-of-order, creating the seq gap, and the same load can make the session.history repull slow or fail — the exact conditions that strand the request.
Same underlying cluster: per-session serial agent turn queue + one shared mux downlink, where a user request is (a) held unprocessed behind the busy turn and (b) only visible once its user/message event is both emitted (loop) and merged (client window). The two symptoms are on the same path:
This issue: the request never appears because, once the event is emitted during the dense-load window, the client window gap/repair strand can drop it from the assembler → permanently invisible.
So it is mostly the same root cause escalated, plus a specific client-side failure mode (gap repair abandoned under load) that turns "delayed" into "never visible".
Expected behavior
A user request must be visible promptly once sent — at minimum as a surfaced "queued / pending / processing" state — and the request text the user typed must always be recoverable in the GUI (owned history, not dependent on the busy agent or the live event stream succeeding).
When a live session/event sequence gap occurs, the buffered events must be reliably repaired (retry with backoff/timeout, or a full resync) so a user/message is never silently stranded; a repair failure must surface an error rather than silently dropping the user's own request from the view.
The folded-request/Trajectory view should not hide content merely because of collapse state or a transient stream failure; fall back to a durable source if the live merge is behind.
Suggested areas to look at
packages/client/runtime/src/client/sessions/session.ts — acceptLiveEvent / repairGap / installWindow gap-and-repair path (add retry/backoff and an explicit stranded-buffer recovery).
packages/client/ui-conversation/src/client/chat/ChatView.tsx and packages/client/ui-trajectory/src/client/TrajectoryTable.tsx — surfacing a "your request is pending/queued" row sourced from the inbox rather than only from emitted user/message events.
packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts + layout.ts — deriving a visible user request placeholder from the dashboard/inbox state even before the user/message event.
packages/client/connection/src/websocket-downlink.ts — serial single-socket pump backpressure is the shared enabler.
Happy to share session-log excerpts (note: this is the same environment/HEAD as discussion #477).
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.
Bug report: under heavy load, NEW user requests no longer appear in the conversation / folded-request (Trajectory) view at all — the user's own history becomes invisible
Environment
dsh web,127.0.0.1:3080)47f943859bObserved behavior
What "collapsed requests" is here
The "collapsed / folded requests" content is produced by the conversation view (
ui-conversation) and the Trajectory view (ui-trajectory), where each user request is rendered as ausercell inside a "Message"/Step Ngroup that can be collapsed per turn/assistant (TrajectoryTablefold state:collapsedTurns/collapsedAssistants). The routing details:packages/client/ui-trajectory/src/client/trajectory-message-definitions.tslines 66–111 — a user request becomes akind:'user'node only from a durableuser/messagesession event (event.type === 'user/message'withsource.kind === 'user').packages/client/ui-trajectory/src/client/layout.tslines 354–366 — thatusernode is placed into the folded request layout as akind:'user'cell (layout.tspushMessage).ChatView.tsxorder.map(...)line 382).TrajectoryTable.tsxlines 571–600, 628–660 — collapsed turns/assistants are hidden behind a summary row, but note line 583 still keepsrequestOnlycells visible in a collapsed turn; so collapse state alone does not fully remove a request. The main cause of "not visible at all" is that the underlyingusernode is never produced.Investigation — why a new request can fail to appear
The request is invisible while queued (shared with discussion [bug] User text input delayed by a long time under heavy concurrent load (queued behind a busy agent turn - no pending feedback) #477). A user request is queued into the agent inbox (
agent.followup→nextTurn,core/agent-loop/src/agent.tslines 122–123). The durableuser/messageevent that the UI renders from is only appended by the loop when the busy turn finally runs that step (agent-loop/src/agent.tsline 283). While queued behind a busy turn, the message has nouser/messageevent yet → nousernode → nothing shows in Chat or the folded-request view.When the event finally arrives but the client event-window has a seq gap under load, it can be stranded. The client session merges live session events through a contiguous event window with gap handling (
packages/client/runtime/src/client/sessions/session.ts):acceptLiveEvent(lines 684–697): ifopenStateis'loading'/'stitching', or the event'sseq > tailSeq + 1(a gap), the event (e.g. theuser/messagefor the user's own request) is pushed intoliveBufferand arepairGap()tail-page repull is kicked off.repairGap(lines 708–724): repullssession.history. If that RPC fails (result.ok === false), the generation went stale (a concurrent resync superseded it), or a transport error throws (caught and justconsole.errorat lines 719–721), the gap is not repaired and the buffered event stays stranded inliveBuffer— it is never applied to theConversationNodeAssembler, so the user request never renders.installWindow(lines 646–665) is the only path that drainsliveBuffer; without a successful tail repull there is no retry/timeout that clears it.The dense-load enabler. All session events (tool chunks,
user/message, turn boundaries) for all ~20 subagents stream over one per-tab mux downlink (packages/client/connection/src/websocket-downlink.tsserialpump, lines 118–137; browser buffer inpackages/client/connection/src/client/web-api-client.ts). Under load aturn/startpreceding the user'suser/messagecan be missed/out-of-order, creating the seq gap, and the same load can make thesession.historyrepull slow or fail — the exact conditions that strand the request.Relationship to issue #477 (delayed input)
Same underlying cluster: per-session serial agent turn queue + one shared mux downlink, where a user request is (a) held unprocessed behind the busy turn and (b) only visible once its
user/messageevent is both emitted (loop) and merged (client window). The two symptoms are on the same path:So it is mostly the same root cause escalated, plus a specific client-side failure mode (gap repair abandoned under load) that turns "delayed" into "never visible".
Expected behavior
session/eventsequence gap occurs, the buffered events must be reliably repaired (retry with backoff/timeout, or a full resync) so auser/messageis never silently stranded; a repair failure must surface an error rather than silently dropping the user's own request from the view.Suggested areas to look at
packages/client/runtime/src/client/sessions/session.ts—acceptLiveEvent/repairGap/installWindowgap-and-repair path (add retry/backoff and an explicit stranded-buffer recovery).packages/client/ui-conversation/src/client/chat/ChatView.tsxandpackages/client/ui-trajectory/src/client/TrajectoryTable.tsx— surfacing a "your request is pending/queued" row sourced from the inbox rather than only from emitteduser/messageevents.packages/client/ui-trajectory/src/client/trajectory-message-definitions.ts+layout.ts— deriving a visibleuserrequest placeholder from the dashboard/inbox state even before theuser/messageevent.packages/client/connection/src/websocket-downlink.ts— serial single-socket pump backpressure is the shared enabler.Happy to share session-log excerpts (note: this is the same environment/HEAD as discussion #477).
All reactions