{"record":{"id":"7d9bd4c61743682f","repo":"facebook/react","slug":"react-element-cannot-be-passed-to-server-functions","errorCode":null,"errorMessage":"React Element cannot be passed to Server Functions from the Client without a temporary reference set. Pass a TemporaryReferenceSet to the options.","messagePattern":"React Element cannot be passed to Server Functions from the Client without a temporary reference set\\. Pass a TemporaryReferenceSet to the options\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-client/src/ReactFlightReplyClient.js","lineNumber":440,"sourceCode":"            const parentReference = writtenObjects.get(parent);\n            if (parentReference !== undefined) {\n              // If the parent has a reference, we can refer to this object indirectly\n              // through the property name inside that parent.\n              const reference = parentReference + ':' + key;\n              // Store this object so that the server can refer to it later in responses.\n              writeTemporaryReference(temporaryReferences, reference, value);\n              return serializeTemporaryReferenceMarker();\n            }\n          }\n          // This element is the root of a serializeModel call (e.g. JSX\n          // passed directly to encodeReply, or a promise that resolved to\n          // JSX). It was already registered as a temporary reference by\n          // serializeModel so we just need to emit the marker.\n          if (temporaryReferences !== undefined && modelRoot === value) {\n            modelRoot = null;\n            return serializeTemporaryReferenceMarker();\n          }\n          throw new Error(\n            'React Element cannot be passed to Server Functions from the Client without a ' +\n              'temporary reference set. Pass a TemporaryReferenceSet to the options.' +\n              (__DEV__ ? describeObjectForErrorMessage(parent, key) : ''),\n          );\n        }\n        case REACT_LAZY_TYPE: {\n          // Resolve lazy as if it wasn't here. In the future this will be encoded as a Promise.\n          const lazy: LazyComponent<any, any> = value as any;\n          const payload = lazy._payload;\n          const init = lazy._init;\n          if (formData === null) {\n            // Upgrade to use FormData to allow us to stream this value.\n            formData = new FormData();\n          }\n          pendingParts++;\n          try {\n            const resolvedModel = init(payload);\n            // We always outline this as a separate part even though we could inline it","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-client/src/ReactFlightReplyClient.js#L422-L458","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait saveConfig({header: <Title>Hello</Title>}); // encodeReply throws\n\n// after\nimport {createTemporaryReferenceSet} from 'react-server-dom-webpack/client';\nconst temporaryReferences = createTemporaryReferenceSet();\nawait callServer(saveConfig.$$id, [{header: <Title>Hello</Title>}], {temporaryReferences});","handlingStrategy":"validation","validationCode":"// Pre-check the argument tree for elements before invoking the server\nconst REACT_ELEMENT = Symbol.for('react.transitional.element');\nfunction containsElement(v, seen = new Set()): boolean {\n  if (v === null || typeof v !== 'object' || seen.has(v)) return false;\n  seen.add(v);\n  if ((v as any).$$typeof === REACT_ELEMENT) return true;\n  return Object.values(v).some(c => containsElement(c, seen));\n}\n// usage:\nif (containsElement(args)) {\n  temporaryReferences = createTemporaryReferenceSet(); // will be required\n}","typeGuard":"const REACT_ELEMENT = Symbol.for('react.transitional.element');\nconst isReactElement = (v: unknown): v is {$$typeof: symbol} =>\n  typeof v === 'object' && v !== null &&\n  (v as any).$$typeof === REACT_ELEMENT;","tryCatchPattern":null,"preventionTips":["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"],"tags":["server-functions","serialization","temporary-references","rsc","react-elements"],"backgroundTag":"missing-temporary-reference-set","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}