facebook/react · critical · Error

525

525

Error message

A React Element from an older version of React was rendered. This is not supported. It can happen if:
- Multiple copies of the "react" package is used.
- A library pre-bundled an old copy of "react" or "react/jsx-runtime".
- A compiler tries to "inline" JSX instead of using the runtime.

What it means

The model serializer met an element whose $$typeof is REACT_LEGACY_ELEMENT_TYPE — the marker used by React versions older than the modern element type. Modern RSC serialization cannot encode legacy elements, so React throws with the three standard causes: duplicate react packages, a library that pre-bundled an old jsx-runtime, or a compiler that hand-inlines JSX instead of emitting runtime imports.

Source

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

              return outlineTask(request, task);
            } else {
              // Forward any debug info we have the first time we see it.
              // We do this after init so that we have received all the debug info
              // from the server by the time we emit it.
              forwardDebugInfo(request, task, debugInfo);
            }
          }
        }
        return renderModelDestructive(
          request,
          task,
          parent,
          parentPropertyName,
          resolvedModel,
        );
      }
      case REACT_LEGACY_ELEMENT_TYPE: {
        throw new Error(
          'A React Element from an older version of React was rendered. ' +
            'This is not supported. It can happen if:\n' +
            '- Multiple copies of the "react" package is used.\n' +
            '- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' +
            '- A compiler tries to "inline" JSX instead of using the runtime.',
        );
      }
    }

    if (isClientReference(value)) {
      return serializeClientReference(
        request,
        parent,
        parentPropertyName,
        value as any,
      );
    }

View on GitHub (pinned to eafeac097b)

Solutions

  1. Run npm ls react / yarn why react and dedupe to exactly one version.
  2. Rebuild or republish the offending library with react and react/jsx-runtime marked external (not bundled).
  3. Configure bundler aliases so every react import resolves to the app's single copy.
  4. If a custom transform inlines JSX, switch it to import from react/jsx-runtime.

Example fix

// before — library bundles its own old jsx-runtime

// after — library build config marks react as external
// rollup.config.js
external: ['react', 'react/jsx-runtime']
Defensive patterns

Strategy: validation

Validate before calling

// Detect legacy elements before they reach the RSC serializer.
const LEGACY_ELEMENT = Symbol.for('react.element');
export function findLegacyElements(node: any, seen = new Set()): string[] {
  if (node == null || typeof node !== 'object' || seen.has(node)) return [];
  seen.add(node);
  if (node.$$typeof === LEGACY_ELEMENT) return [String(node.type)];
  const out: string[] = [];
  for (const k in node) out.push(...findLegacyElements(node[k], seen));
  if (Symbol.iterator in node) for (const c of node) out.push(...findLegacyElements(c, seen));
  return out;
}

Type guard

export function isLegacyElement(v: unknown): boolean {
  return typeof v === 'object' && v !== null && (v as any).$$typeof === Symbol.for('react.element');
}

Prevention

When it happens

Trigger: A dependency ships a bundle that inlined its own old react/jsx-runtime at publish time; two react versions resolve within one server graph; a custom Babel/SWC transform emitting plain createElement-style objects instead of importing the JSX runtime.

Common situations: Old component libraries published as prebuilt bundles; monorepos with mixed react versions after a partial upgrade; MDX or custom compilers constructing elements by hand; CDN-compiled code pasted into a project.

Related errors


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