gotchatypescriptnextjsMinor
RSC: server-created elements passed as props to a client component trigger intermittent "unique key" warnings after a Server Action refresh
Viewed 0 times
React 19+, Next.js 15/16 App Router
unique key propserver action refreshlazy flight chunkprops as elementswarnForMissingKeyintermittent warning
browserssrnodejs
Error Messages
Problem
A server page passes JSX elements as props (filters={<Filters/>}, pipeline={{ pill: <Menu/> }}) to a client component that renders them next to its own children. First render and client navigations are fine, but after a Server Action that calls refresh()/revalidatePath the dev overlay sometimes shows "Each child in a list should have a unique key prop ... It was passed a child from <ServerPage>". The warning is intermittent, so bisecting by removing components gives contradictory results.
Solution
Give a stable key to every element the server creates and passes as a prop or slot to a client component, even when rendered once: <Filters key="filters" />, <Menu key="pill" />, <SettingsPanel key="settings" />. Or pass plain data and let the client component create the element. To find the culprit reliably, set a CDP breakpoint on
child._store.validated = 1 inside warnForMissingKey in the react-dom client dev chunk and evaluate child.type, child.key, child._owner on the call frame; repeat the action several times because the warning is timing dependent.Why
Flight sends such props as lazy references; when they resolve after an action refresh, React reconciles them inside the client component's children array and validates keys. Server elements created outside an array keep _store.validated = 0 and key null, so warnForMissingKey fires only when the lazy path is taken. The warning is also deduplicated per component name per page load.
Gotchas
- Keys on the client component's own children do not help: the unkeyed elements are the props created on the server.
- Full page loads and client navigations do not show the warning, only action refreshes, and not every time.
Code Snippets
Key each element passed as a prop
<Bar filters={<Filters key="filters" {...f} />} pipeline={{ pill: <Menu key="pill" {...p} /> }} panel={open && <Settings key="settings" />} />Context
In development, after a Server Action response that refreshes the page (refresh(), revalidatePath).
Revisions (0)
No revisions yet.