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

  1. Remove server references and form actions from the tree passed to renderToHTML; pass plain serializable data instead.
  2. If you need server actions, render with a Flight/SSR API (renderToReadableStream plus Flight) rather than renderToHTML.
  3. 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

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


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/85901d80d6d21c65. Report an issue: GitHub.