facebook/react · warning

You did not run Node.js with the `--conditions react-server`

Error message

You did not run Node.js with the `--conditions react-server` flag. Any "react-server" override will only work with ESM imports.

What it means

The react-server-dom-esm Node loader (registered via register() from react-server-dom-esm/server) hooks module resolution so packages can ship a server-only 'react-server' export. Node only passes its process-level conditions into the hook, so if node was not started with --conditions react-server, the loader appends the condition to each resolve call (ReactFlightESMNodeLoader.js:82) and warns once that the override applies only to ESM imports resolved through the hooks - CommonJS require() bypasses them entirely.

Source

Thrown at packages/react-server-dom-esm/src/ReactFlightESMNodeLoader.js:82

let stashedResolve: null | ResolveFunction = null;

export async function resolve(
  specifier: string,
  context: ResolveContext,
  defaultResolve: ResolveFunction,
): Promise<{url: string}> {
  // We stash this in case we end up needing to resolve export * statements later.
  stashedResolve = defaultResolve;

  if (!context.conditions.includes('react-server')) {
    context = {
      ...context,
      conditions: [...context.conditions, 'react-server'],
    };
    if (!warnedAboutConditionsFlag) {
      warnedAboutConditionsFlag = true;
      // eslint-disable-next-line react-internal/no-production-logging
      console.warn(
        'You did not run Node.js with the `--conditions react-server` flag. ' +
          'Any "react-server" override will only work with ESM imports.',
      );
    }
  }
  return await defaultResolve(specifier, context, defaultResolve);
}

export async function getSource(
  url: string,
  context: GetSourceContext,
  defaultGetSource: GetSourceFunction,
): Promise<{source: Source}> {
  // We stash this in case we end up needing to resolve export * statements later.
  stashedGetSource = defaultGetSource;
  return defaultGetSource(url, context, defaultGetSource);
}

View on GitHub (pinned to eafeac097b)

Solutions

  1. Start node with the flag: node --conditions react-server server.js
  2. Bake it into package.json scripts, Dockerfiles, and Procfiles so every entry point inherits it
  3. If a wrapper swallows CLI flags, set NODE_OPTIONS='--conditions react-server' or spawn node programmatically with execArgv
  4. Convert CJS entry points to ESM - the loader-level condition never covers require() resolution

Example fix

// before
"scripts": { "start": "node server.js" }

// after
"scripts": { "start": "node --conditions react-server server.js" }
Defensive patterns

Strategy: validation

Validate before calling

// fail fast before registering the loader
const args = process.execArgv.join(' ');
if (!args.includes('--conditions') || !args.includes('react-server')) {
  throw new Error(
    `Start the server with: node --conditions react-server ${process.argv[1]}`,
  );
}
register(); // from 'react-server-dom-esm/server'

Prevention

When it happens

Trigger: Running `node server.js` where server.js calls register() from 'react-server-dom-esm/server' (or is launched with --import/--loader pointing at it) without --conditions react-server. The first specifier resolved after that triggers the one-time warning.

Common situations: Custom React Server Components node servers; tooling wrappers (tsx, nodemon, pm2, ts-node) that spawn node without forwarding flags; a CJS bootstrap requiring the ESM entry, where the injected condition never applies.

Related errors


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