fix(chat): useChatSend drops concurrent user messages while a prior send is in flight (#2700 feature 2) #2725

Closed
opened 2026-06-13 07:43:11 +00:00 by agent-dev-a · 0 comments
Member

Bug

useChatSend.ts:160 early-returns when sending or sendInFlightRef.current is true. If a user sends a second message while the first reply is still pending, the second message is silently dropped.

Root cause

The hook uses single global state/refs for in-flight tracking:

  • sending: boolean
  • sendInFlightRef: boolean
  • sendTokenRef: number (single latest token)

This assumes at most one in-flight send, so a 2nd send is rejected and only the latest token's response is processed.

Expected behavior (#2700 feature 2)

  1. A 2nd message is NOT dropped while the 1st is pending.
  2. The thinking indicator stays active while ANY send is pending.
  3. Replies are not misrouted between concurrent sends.

Fix shape

Replace the single in-flight boolean/counter with a Set of in-flight send tokens. Remove the sending/sendInFlightRef early-return. Each .then/.catch checks whether its own token is still in the set before processing. sending is derived from set.size > 0.

Test plan

  • Add unit tests covering two rapid sends, verifying both optimistic bubbles are appended, both A2A requests fire, and replies are matched to the correct send token.
  • Add test verifying the thinking indicator stays active until the last pending send completes.

Refs #2700.

## Bug `useChatSend.ts:160` early-returns when `sending` or `sendInFlightRef.current` is true. If a user sends a second message while the first reply is still pending, the second message is **silently dropped**. ## Root cause The hook uses single global state/refs for in-flight tracking: - `sending: boolean` - `sendInFlightRef: boolean` - `sendTokenRef: number` (single latest token) This assumes at most one in-flight send, so a 2nd send is rejected and only the latest token's response is processed. ## Expected behavior (#2700 feature 2) 1. A 2nd message is NOT dropped while the 1st is pending. 2. The thinking indicator stays active while ANY send is pending. 3. Replies are not misrouted between concurrent sends. ## Fix shape Replace the single in-flight boolean/counter with a `Set` of in-flight send tokens. Remove the `sending`/`sendInFlightRef` early-return. Each `.then`/`.catch` checks whether its own token is still in the set before processing. `sending` is derived from `set.size > 0`. ## Test plan - Add unit tests covering two rapid sends, verifying both optimistic bubbles are appended, both A2A requests fire, and replies are matched to the correct send token. - Add test verifying the thinking indicator stays active until the last pending send completes. Refs #2700.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2725