Symptom: a generative UI built with createStreamableUI updates sluggishly or the final state never arrives. The stream seems stuck.

Cause: the streamable was never closed. The client keeps waiting for more parts because the stream is still open server-side.

Confirmation:
1. Find the createStreamableUI call. Trace every code path (including early returns and catch blocks) and check whether .done() is reached on all of them.
2. If any path returns stream.value without calling stream.done() first, that is the bug. Exceptions thrown between update() and done() are the classic.

Fix:

import { createStreamableUI } from '@ai-sdk/rsc';

const stream = createStreamableUI('initial');
try {
  stream.update('working...');
  // ... do work ...
  stream.done('final');
} catch (e) {
  stream.done('failed');
}
return stream.value;

Rules:
1. Always close with .done(), even on error paths. try/finally is the safest shape.
2. .done() takes the final value. .update() and .append() are for intermediate states.
3. This applies to the @ai-sdk/rsc streamable UI path. The newer tool-part generative UI pattern (tools returning data rendered by React components) does not have this failure mode; prefer it for new code.
4. If updates are slow but do finish, check that you are not awaiting the full model response before the first update. Stream early, stream often.

Verification: exercise the error path deliberately and confirm the UI reaches its final state instead of hanging.