Skip to content

useAgentChat stays stuck streaming after chatRecovery continues under a new request id #1485

@ThomasKliszowski

Description

@ThomasKliszowski

Describe the bug

When an AIChatAgent with chatRecovery = true recovers an interrupted chat stream, the recovered server-side continuation can complete under a new request id while the browser-side useAgentChat / AI SDK useChat state remains stuck streaming.

The UI can keep reporting chat.status === "streaming" and chat.isStreaming === true even after recovery has finished.

To Reproduce

Steps to reproduce the behavior:

  1. Clone/run this minimal repro: https://github.com/ThomasKliszowski/cloudflare-ai-chat-recovery-stuck-stream-repro.

  2. Install dependencies:

    npm install
  3. Start the Worker:

    npm run dev:worker
  4. In another terminal, start the client:

    npm run dev
  5. Open http://localhost:5173.

  6. Click Start slow stream.

  7. Wait until the page shows Ready for restart.

  8. Stop the Worker with Ctrl-C.

  9. Restart the Worker:

    npm run dev:worker
  10. Wait for the browser to reconnect and for the server-side recovery continuation to finish.

  11. Observe that the page can show Bug reproduced: the recovery continuation was received, but chat.status / isStreaming still indicate that the original browser stream is active.

Expected behavior

After the recovered continuation completes, the browser-side chat state should return to idle:

  • chat.status should no longer be "streaming" or "submitted".
  • chat.isStreaming should become false.
  • The original browser request should no longer be considered active.

Version

Observed with:

  • agents@0.12.3
  • @cloudflare/ai-chat@0.6.2
  • ai@6.0.168
  • @ai-sdk/react@3.0.170

Additional context

The suspected cause is that WebSocketChatTransport.sendMessages() creates a local ReadableStream for the original request id. When chatRecovery takes over, the server sends continuation frames with continuation: true under a new request id.

Those continuation frames complete successfully, but they do not close or resolve the original local ReadableStream. As a result, AI SDK useChat can keep the original request in streaming state indefinitely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions