facebook/react · error · Error
535
535
Error message
renderToHTML should not have emitted Server References. This is a bug in React.
What it means
experimental_renderToHTML round-trips its tree through an embedded Flight response built with noServerCallOrFormAction wired into the response's server-reference hooks. If the tree contains a Server Reference (a 'use server' function, a form action, or a serialized server closure), decoding that reference invokes the stub, which throws - by policy, renderToHTML output must be inert HTML with no callable references.
Source
Thrown at packages/react-markup/src/ReactMarkupServer.js:74
| symbol
| null
| void
| bigint
| $AsyncIterable<ReactMarkupNodeList, ReactMarkupNodeList, void>
| $AsyncIterator<ReactMarkupNodeList, ReactMarkupNodeList, void>
| Iterable<ReactMarkupNodeList>
| Iterator<ReactMarkupNodeList>
| Array<ReactMarkupNodeList>
| Promise<ReactMarkupNodeList>; // Thenable<ReactMarkupNodeList>
type MarkupOptions = {
identifierPrefix?: string,
signal?: AbortSignal,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
};
function noServerCallOrFormAction() {
throw new Error(
'renderToHTML should not have emitted Server References. This is a bug in React.',
);
}
export function experimental_renderToHTML(
children: ReactMarkupNodeList,
options?: MarkupOptions,
): Promise<string> {
return new Promise((resolve, reject) => {
const flightResponse = createFlightResponse(
null,
null,
null,
noServerCallOrFormAction,
noServerCallOrFormAction,
undefined,
undefined,
false,View on GitHub (pinned to eafeac097b)
Solutions
- Remove server references and form actions from the tree passed to renderToHTML; pass plain serializable data instead.
- If you need server actions, render with a Flight/SSR API (renderToReadableStream plus Flight) rather than renderToHTML.
- If the tree is provably reference-free and this still throws, capture the component stack and file a React issue - the message itself marks it as a React bug.
Example fix
// before
await experimental_renderToHTML(
<form action={createOrder}>...</form>,
); // createOrder is a 'use server' function
// after
await experimental_renderToHTML(
<form method='post' action='/api/order'>...</form>,
); Defensive patterns
Strategy: try-catch
Try / catch
try {
const html = await experimental_renderToHTML(tree, {
onError: (e) => {
console.error(e);
return '<!-- render error -->';
},
});
} catch (e) {
if (/Server References/.test(e.message)) {
// fall back to a reference-free tree (plain data instead of server functions)
const html = await experimental_renderToHTML(sanitizeTree(tree));
} else {
throw e;
}
} Prevention
- Keep 'use server' functions and form actions out of trees passed to renderToHTML.
- Pass plain serializable data (ids, URLs) and let the client call APIs instead.
- Add a review check that greps the static-markup tree's modules for server-reference imports.
When it happens
Trigger: Passing a server-reference value into experimental_renderToHTML: a function from a 'use server' module, action={serverAction} on a form or button, or a child component that internally renders server references.
Common situations: Reusing RSC/Flight trees in a static-markup pipeline; forms built with server actions rendered to static HTML; passing almost-serializable props where one value is a server function.
Related errors
- getProfilingData not supported by this renderer
- createFastHash is not supported in this environment.
- 417
- 536
- 537
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/85901d80d6d21c65.
Report an issue: GitHub.