facebook/react · critical · Error

react-cache: Unsupported React version

Error message

react-cache: Unsupported React version

What it means

At module load, react-devtools-shared's cache probes the host React for either React.use (React 19+) or __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher (React 16.6–18) to implement readContext. If neither exists it throws 'react-cache: Unsupported React version' while the module is being imported, taking the whole DevTools bundle down with it.

Source

Thrown at packages/react-devtools-shared/src/devtools/cache.js:66

} else if (
  typeof (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ===
  'object'
) {
  const ReactCurrentDispatcher = (React as any)
    .__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;
  readContext = function (Context: ReactContext<null>) {
    const dispatcher = ReactCurrentDispatcher.current;
    if (dispatcher === null) {
      throw new Error(
        'react-cache: read and preload may only be called from within a ' +
          "component's render. They are not supported in event handlers or " +
          'lifecycle methods.',
      );
    }
    return dispatcher.readContext(Context);
  };
} else {
  throw new Error('react-cache: Unsupported React version');
}

const CacheContext = createContext(null);

type Config = {useWeakMap?: boolean, ...};

const entries: Map<
  Resource<any, any, any>,
  Map<any, any> | WeakMap<any, any>,
> = new Map();
const resourceConfigs: Map<Resource<any, any, any>, Config> = new Map();

function getEntriesForResource(
  resource: any,
): Map<any, any> | WeakMap<any, any> {
  let entriesForResource: Map<any, any> | WeakMap<any, any> = entries.get(
    resource,
  ) as any as Map<any, any>;

View on GitHub (pinned to eafeac097b)

Solutions

  1. Upgrade the host react/react-dom to 16.8+ (or 19+ for the React.use path).
  2. Hunt duplicates: npm ls react / yarn why react, and make devtools resolve the same React copy the app uses.
  3. Fix test mocks: jest.mock('react') with requireActual, so __SECRET_INTERNALS survive.

Example fix

// before — package.json
"react": "^15.6.0"

// after
"react": "^18.3.1"
Defensive patterns

Strategy: validation

Validate before calling

function supportsDevToolsCache(React) {
  return (
    typeof React.use === 'function' ||
    (React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED != null &&
      React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher != null)
  );
}
if (!supportsDevToolsCache(require('react'))) {
  throw new Error('Upgrade React to 16.8+ before loading DevTools');
}

Type guard

function supportsDevToolsCache(React) {
  return (
    typeof React.use === 'function' ||
    (React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED != null &&
      React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher != null)
  );
}

Prevention

When it happens

Trigger: Importing react-devtools-shared (or anything that pulls in devtools/cache) in an environment whose 'react' module exposes neither React.use nor the secret-internals object — e.g. React < 16.6, a jest.mock('react') stub, or a React-mocking shim in tests.

Common situations: Unit tests that mock 'react' without preserving internals; resolving a different/older React duplicate than the one devtools was built against; embedding DevTools packages into an app pinned to an old React.

Related errors


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