facebook/react · critical · Error

458

458

Error message

Currently React only supports one RSC renderer at a time.

What it means

Starting an RSC request installs ReactSharedInternals.A as the Flight async dispatcher, and React permits only one RSC dispatcher per loaded React copy — it is kept installed permanently for the process. The guard fires when the slot already holds a dispatcher that is not the Flight DefaultAsyncDispatcher, which is the signature of two different RSC runtime copies (or an incompatible dispatcher) sharing one realm.

Solutions

  1. Run npm ls react react-server react-server-dom-webpack (or yarn why) and remove duplicates via overrides/resolutions.
  2. Import the RSC server APIs from a single module instance — one entry point, one chunk graph.
  3. Align react, react-server-dom-* and framework versions so exactly one copy resolves everywhere.

Example fix

// before — npm ls react shows 19.0.0 and 19.1.0 in the same server bundle

// after — package.json forces one copy
"overrides": { "react": "19.1.0", "react-dom": "19.1.0" }
Defensive patterns

Strategy: validation

Validate before calling

// Boot-time check: the react resolved from app code and from the RSC runtime must match.
import {createRequire} from 'module';
const require = createRequire(import.meta.url);
const appReact = require.resolve('react');
const rscReact = require.resolve('react', {paths: [require.resolve('react-server-dom-webpack/server')]});
if (appReact !== rscReact) {
  throw new Error(`Two react copies: ${appReact} vs ${rscReact} — dedupe before starting.`);
}

Prevention

When it happens

Trigger: Loading two copies of react-server/react-server-dom-* (one via require, one via a bundled ESM build) and calling render()/prerender() from both; npm hoisting mismatches where react resolves to different versions inside and outside the server bundle; mixing a framework's compiled RSC runtime with direct react-server-dom-webpack imports.

Common situations: Monorepos or bundlers that vendor react-server separately per entry point; frameworks (Next.js, Waku) plus direct Flight imports in the same server; upgrading react without upgrading react-server-dom-* in lockstep.

Related errors


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

Appendix: source

Thrown at packages/react-server/src/ReactFlightServer.js:702

  this: $FlowFixMe,
  type: 20 | 21,
  model: ReactClientValue,
  bundlerConfig: ClientManifest,
  onError: void | ((error: mixed) => ?string),
  onAllReady: () => void,
  onFatalError: (error: mixed) => void,
  identifierPrefix?: string,
  temporaryReferences: void | TemporaryReferenceSet,
  debugStartTime: void | number, // Profiling-only
  environmentName: void | string | (() => string), // DEV-only
  filterStackFrame: void | ((url: string, functionName: string) => boolean), // DEV-only
  keepDebugAlive: boolean, // DEV-only
) {
  if (
    ReactSharedInternals.A !== null &&
    ReactSharedInternals.A !== DefaultAsyncDispatcher
  ) {
    throw new Error(
      'Currently React only supports one RSC renderer at a time.',
    );
  }
  ReactSharedInternals.A = DefaultAsyncDispatcher;
  if (__DEV__) {
    // Unlike Fizz or Fiber, we don't reset this and just keep it on permanently.
    // This lets it act more like the AsyncDispatcher so that we can get the
    // stack asynchronously too.
    ReactSharedInternals.getCurrentStack = getCurrentStackInDEV;
  }

  const abortSet: Set<Task> = new Set();
  const pingedTasks: Array<Task> = [];
  const cleanupQueue: Array<string | bigint> = [];
  if (enableTaint) {
    TaintRegistryPendingRequests.add(cleanupQueue);
  }
  const hints = createHints();

View on GitHub (pinned to eafeac097b)