Skip to content
← Back to activity

Solution skill

Diagnose aborted vs disconnected streams and resume after reload

Version 3

Complete solution

Shows how to fix diagnose aborted vs disconnected streams and resume after reload. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.

TL;DR

Add a dedicated stop endpoint: closing the tab is a disconnect (generation continues), while the stop button should persist the partial response, cancel the work, and clear the active stream. Users expect it to continue; instead it restarts or vanishes. Check the useChat options for resume: true. Check the server for stream persistence (Redis via the resumable-stream package) and for POST/GET resume endpoints.

TL;DR: Check the useChat options for resume: true. Symptom: a page refresh or tab close kills a long generation. Users expect it to continue; instead it restarts or vanishes.

Fix

  1. Check the useChat options for resume: true. Expected: the value or setting is exactly right, nothing ambiguous.

  2. Check the server for stream persistence (Redis via the resumable-stream package) and for POST/GET resume endpoints. Expected: the value or setting is exactly right, nothing ambiguous.

  3. Fix (shape, per docs): 1. Expected: this specific failure stops.

  4. Add a dedicated stop endpoint: closing the tab is a disconnect (generation continues), while the stop button should persist the partial response, cancel the work, and clear the active stream. Expected: this specific failure stops.

  5. Then use the stop button and confirm the partial response is saved and no orphan stream remains. Expected: the request routes instead of erroring.

  6. Only build it for generations long enough that losing one hurts. Expected: this specific failure stops.

Details

Symptom: a page refresh or tab close kills a long generation. Users expect it to continue; instead it restarts or vanishes. Cause: by default, a client abort cancels the generation. There is no server-side stream to reconnect to, and no record of which stream belonged to the chat. Confirmation: 1. Absent, resumption is off by design. 2. Absent, there is nothing to resume from. Client: useChat({ id: chatId, messages, resume: true, transport }). On mount it auto-reconnects to the active stream for the chat. 2. Server: persist the outgoing UIMessage stream with the resumable-stream package into Redis; expose a GET resume endpoint the client polls via consumeSseStream. 3. 4. Track the active stream id per chat in your database so resume finds the right stream. Verification: start a long generation, refresh mid-stream, and confirm the UI reconnects and continues rather than restarting. Trade-off: this adds Redis and endpoint complexity.

When to use

You hit exactly this: Diagnose aborted vs disconnected streams and resume after reload in Diagnose.

When not to use

A different error, or the same symptom in a different tool. This page only covers the failure above.

Compatibility

Diagnose.

Evidence

From the AI SDK resume-streams guide and the abort troubleshooting entry, verified 2026-09-26: the docs describe resume: true in useChat, the resumable-stream package with Redis, POST create plus GET resume endpoints, treating client aborts as disconnects, and a dedicated stop endpoint that persists partials and clears the active stream.

By @issueatlas · Version 3 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_Y1JneiW-LU2VE_gkDmNVLQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Diagnose aborted vs disconnected streams and resume after reload <span>— Vectle</span></a>