facebook/react · error · Error

533

533

Error message

Attempted to render a Server Action from renderToHTML. This is not supported since it varies by version of the app. Use a fixed URL for any forms instead.

What it means

In renderToHTML (static markup) mode, Server Actions cannot be rendered because their generated IDs vary between builds and deployments of the app, so embedding one in immutable HTML would produce a stale action URL. The markup config fork implements getServerReferenceId by throwing instead of assigning an ID.

Source

Thrown at packages/react-server/src/forks/ReactFlightServerConfig.markup.js:91

  );
}

export function resolveClientReferenceMetadata<T>(
  config: ClientManifest,
  clientReference: ClientReference<T>,
): ClientReferenceMetadata {
  throw new Error(
    'Attempted to render a Client Component from renderToHTML. ' +
      'This is not supported since it will never hydrate. ' +
      'Only render Server Components with renderToHTML.',
  );
}

export function getServerReferenceId<T>(
  config: ClientManifest,
  serverReference: ServerReference<T>,
): ServerReferenceId {
  throw new Error(
    'Attempted to render a Server Action from renderToHTML. ' +
      'This is not supported since it varies by version of the app. ' +
      'Use a fixed URL for any forms instead.',
  );
}

export function getServerReferenceBoundArguments<T>(
  config: ClientManifest,
  serverReference: ServerReference<T>,
): null | Array<ReactClientValue> {
  throw new Error(
    'Attempted to render a Server Action from renderToHTML. ' +
      'This is not supported since it varies by version of the app. ' +
      'Use a fixed URL for any forms instead.',
  );
}

export function getServerReferenceLocation<T>(

View on GitHub (pinned to eafeac097b)

Solutions

  1. Replace the server action in the form with a fixed URL string action (e.g. action="/api/submit") as the error message advises
  2. Remove the server action from the statically rendered tree and invoke it from an interactive client component after hydration
  3. Use a streaming/hydrating renderer (renderToPipeableStream) instead of renderToHTML when server actions must be embedded

Example fix

// before
'use server';
async function createPost(formData) { /* ... */ }
// static page:
<form action={createPost}>...</form> // throws in renderToHTML

// after
<form method="post" action="/api/create-post">...</form>
Defensive patterns

Strategy: validation

Validate before calling

// Reject server references before static rendering
const isServerReference = (fn: any): boolean =>
  typeof fn === 'function' &&
  (fn.$$typeof === Symbol.for('react.server.reference') || Boolean(fn.bind && fn.$$id));

function assertFormActionsAreFixed(element) {
  if (element?.props?.action != null && isServerReference(element.props.action)) {
    throw new TypeError('Use a fixed URL action, not a server action, in static HTML');
  }
}

Type guard

const isServerAction = (v: any): boolean =>
  typeof v === 'function' && v.$$typeof === Symbol.for('react.server.reference');

Prevention

When it happens

Trigger: Rendering a 'use server' function reference with renderToHTML, e.g. <form action={serverAction}> where serverAction is a server reference, causing the Flight server to request its ID.

Common situations: Prerendering a page with progressive-enhancement forms that point at server actions; copying a form with an action prop from a streaming RSC app into a static renderToHTML pipeline.

Related errors


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