-
Notifications
You must be signed in to change notification settings - Fork 437
Description
Problem
WebSocketChatTransport.reconnectToStream() sends CF_AGENT_STREAM_RESUME_REQUEST after a fixed 100ms setTimeout, but after a page refresh the WebSocket hasn't opened yet at that point. The agent.send() throws, the try/catch swallows it, and after the 3s timeout the method returns null → status stays "ready".
Result: After refreshing during an active stream, the text eventually appears (via onAgentMessage), but useChat status never transitions to "streaming" — no abort button, no loading indicator.
Where
WebSocketChatTransport.reconnectToStream() in packages/ai-chat/src/react.ts:
const requestDelay = setTimeout(() => {
if (!resolved) try {
agent.send(JSON.stringify({ type: MessageType.CF_AGENT_STREAM_RESUME_REQUEST }));
} catch {}
}, 100);The 100ms delay was added to avoid a race with the server's automatic CF_AGENT_STREAM_RESUMING in onConnect, but it doesn't account for WebSocket connection time — which is almost always longer than 100ms on a fresh page load.
Suggested fix
Wait for the WebSocket to be open before sending:
function sendWhenOpen(agent, message) {
if (agent.readyState === WebSocket.OPEN) {
agent.send(message);
} else {
agent.addEventListener("open", () => agent.send(message), { once: true });
}
}Related
Follow-up to the fix in PR #999 (which fixed the ReadableStream return from reconnectToStream). The transport pipeline works correctly once the request actually reaches the server — the only issue is the send timing.
See also #896 (comment): #896 (comment)