Solution skill
RSC and client boundaries: where streamText may run and where useChat must live
Complete solution
Shows how to fix rSC and client boundaries: where streamText may run and where useChat must live. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
When it applies
Not specified by the original author.
Instructions
TL;DR
- streamText and generateText run in route handlers, server actions, or server components. Never in a 'use client' component.
Steps
- Most Next.js AI SDK bugs are boundary bugs: server code in the client, or client hooks in server components. The rules are simple.
- streamText and generateText run in route handlers, server actions, or server components. Never in a 'use client' component. The provider key lives server-side; calling from the client would expose it and fail on missing env.
- useChat, useCompletion, and useObject are client hooks. They must live in a file with 'use client' at the top. Putting them in a server component is a build error.
- The page pattern: a server component (or plain page) renders a 'use client' chat component. The chat component owns useChat and talks to /api/chat over HTTP. The route handler owns streamText.
- Only serializable data crosses the boundary. UIMessage objects are plain JSON and cross fine. Functions, class instances, and streams do not.
- Do not import server-only modules (ai provider factories with keys are fine, but never the key itself) into client components. If a client file imports something that reads process.env keys at module scope, that key can end up in the client bundle.
- Server Actions are an alternative to route handlers for simple calls, but streaming from a server action has sharp edges (see the docs troubleshooting on server actions in client components). Prefer route handlers for streaming chat.
- generateId from ai is safe to use anywhere, including client components, for chat IDs and message keys.
When to use
You are seeing this: Most Next.js AI SDK bugs are boundary bugs: server code in the client, or client hooks in server components. Use this skill when you run into "RSC and client boundaries: where streamText may run and where useChat must live".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
Why this happens
The original report does not dig into a root cause. It documents the symptom and the fix that resolved it.
Evidence
Verified against the live AI SDK docs 2026-09-26. The Next.js App Router quickstart separates the route handler (server) from the page component ('use client' with useChat). The troubleshooting index includes server-actions-in-client-components as a known issue category. The message-persistence guide uses generateId from ai for chat IDs.
By @issueatlas · Version 2 · Exact version
Maintainer review
Checking maintainer review for this exact version…
A maintainer review records the library version checked. It does not assert that it is the latest upstream release. Reported outcomes are separate evidence.
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_RTuMA1GG3hfzqG525e_UDQ" 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">RSC and client boundaries: where streamText may run and where useChat must live <span>— Vectle</span></a>