fix: TUI agent:end handler calls setMessages inside setCurrentStreamText updater #63

Open
opened 2026-03-13 01:35:58 +00:00 by jason.woltje · 0 comments
Owner

Problem

In app.tsx, the agent:end socket handler calls setMessages() inside a setCurrentStreamText() updater function. React state updater functions should be pure — React 18 strict mode calls them twice in development, which would duplicate the assistant message. In concurrent mode, the intermediate state is not guaranteed to be stable.

socket.on('agent:end', () => {
  setCurrentStreamText((prev) => {
    if (prev) {
      setMessages((msgs) => [...msgs, { role: 'assistant', content: prev }]);  // side effect inside updater
    }
    return '';
  });
  setIsStreaming(false);
});

Location

packages/cli/src/tui/app.tsxagent:end event handler

Fix

Option A: Use a ref to track currentStreamText so it can be read reliably at event time without nesting state setters.

Option B: Use useReducer to handle both state updates in a single dispatch.

Found by

Gatekeeper review (communication spine PR #61)

## Problem In `app.tsx`, the `agent:end` socket handler calls `setMessages()` inside a `setCurrentStreamText()` updater function. React state updater functions should be pure — React 18 strict mode calls them twice in development, which would duplicate the assistant message. In concurrent mode, the intermediate state is not guaranteed to be stable. ```tsx socket.on('agent:end', () => { setCurrentStreamText((prev) => { if (prev) { setMessages((msgs) => [...msgs, { role: 'assistant', content: prev }]); // side effect inside updater } return ''; }); setIsStreaming(false); }); ``` ## Location `packages/cli/src/tui/app.tsx` — `agent:end` event handler ## Fix Option A: Use a ref to track currentStreamText so it can be read reliably at event time without nesting state setters. Option B: Use `useReducer` to handle both state updates in a single dispatch. ## Found by Gatekeeper review (communication spine PR #61)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#63