facebook/react · error · Error
React Element cannot be passed to Server Functions from the
Error message
React Element cannot be passed to Server Functions from the Client without a temporary reference set. Pass a TemporaryReferenceSet to the options.
What it means
When serializeReply (encodeReply) walks arguments for a Server Function call, React Elements cannot be represented in the Flight reply protocol by value - they must be registered in a TemporaryReferenceSet that the server later reads back. If no temporaryReferences option was passed, there is nowhere to record the element and the serializer throws, telling you to pass a TemporaryReferenceSet in the options.
Source
Thrown at packages/react-client/src/ReactFlightReplyClient.js:440
const parentReference = writtenObjects.get(parent);
if (parentReference !== undefined) {
// If the parent has a reference, we can refer to this object indirectly
// through the property name inside that parent.
const reference = parentReference + ':' + key;
// Store this object so that the server can refer to it later in responses.
writeTemporaryReference(temporaryReferences, reference, value);
return serializeTemporaryReferenceMarker();
}
}
// This element is the root of a serializeModel call (e.g. JSX
// passed directly to encodeReply, or a promise that resolved to
// JSX). It was already registered as a temporary reference by
// serializeModel so we just need to emit the marker.
if (temporaryReferences !== undefined && modelRoot === value) {
modelRoot = null;
return serializeTemporaryReferenceMarker();
}
throw new Error(
'React Element cannot be passed to Server Functions from the Client without a ' +
'temporary reference set. Pass a TemporaryReferenceSet to the options.' +
(__DEV__ ? describeObjectForErrorMessage(parent, key) : ''),
);
}
case REACT_LAZY_TYPE: {
// Resolve lazy as if it wasn't here. In the future this will be encoded as a Promise.
const lazy: LazyComponent<any, any> = value as any;
const payload = lazy._payload;
const init = lazy._init;
if (formData === null) {
// Upgrade to use FormData to allow us to stream this value.
formData = new FormData();
}
pendingParts++;
try {
const resolvedModel = init(payload);
// We always outline this as a separate part even though we could inline itView on GitHub (pinned to eafeac097b)
Solutions
- Create a TemporaryReferenceSet and pass it: const temporaryReferences = createTemporaryReferenceSet(); await encodeReply(args, {temporaryReferences})
- Thread the same set to the server decoder (decodeReply(body, {temporaryReferences})) so both ends resolve the same ids
- Scope the set per request and reuse it for the whole round-trip; do not create a second set mid-flight
- If you did not mean to send elements, send serializable data (props/ids) and render the element on the server instead
Example fix
// before
await saveConfig({header: <Title>Hello</Title>}); // encodeReply throws
// after
import {createTemporaryReferenceSet} from 'react-server-dom-webpack/client';
const temporaryReferences = createTemporaryReferenceSet();
await callServer(saveConfig.$$id, [{header: <Title>Hello</Title>}], {temporaryReferences}); Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the argument tree for elements before invoking the server
const REACT_ELEMENT = Symbol.for('react.transitional.element');
function containsElement(v, seen = new Set()): boolean {
if (v === null || typeof v !== 'object' || seen.has(v)) return false;
seen.add(v);
if ((v as any).$$typeof === REACT_ELEMENT) return true;
return Object.values(v).some(c => containsElement(c, seen));
}
// usage:
if (containsElement(args)) {
temporaryReferences = createTemporaryReferenceSet(); // will be required
} Type guard
const REACT_ELEMENT = Symbol.for('react.transitional.element');
const isReactElement = (v: unknown): v is {$$typeof: symbol} =>
typeof v === 'object' && v !== null &&
(v as any).$$typeof === REACT_ELEMENT; Prevention
- Standardize on one callServer helper that always creates and threads a TemporaryReferenceSet
- Prefer sending data (props/ids) over elements when the server can render the UI itself
- Type Server Function signatures to accept serializable types, not ReactNode
When it happens
Trigger: Passing JSX or React Elements (e.g. {node: <Foo/>} or children) as arguments to a Server Function, or as the root of encodeReply, without an options object containing temporaryReferences; also elements nested deeper inside objects/arrays in the argument tree.
Common situations: Sending rendered UI snippets (rich content, slot fills) to server actions; libraries that accept ReactNode payloads from the client; hand-rolled encodeReply/decodeReply plumbing where the per-request set was not created or threaded.
Related errors
- Missing a temporary reference set but the RSC response retur
- Symbols cannot be passed to a Server Function without a temp
- Only plain objects, and a few built-ins, can be passed to Se
- Client Functions cannot be passed directly to Server Functio
- Type ${typeof value} is not supported as an argument to a Se
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/7d9bd4c61743682f.
Report an issue: GitHub.