facebook/relay · error

relay-runtime requires ${[mapStr, setStr, promiseStr, objStr

Error message

relay-runtime requires ${[mapStr, setStr, promiseStr, objStr].filter(Boolean).join(', and ')} to exist. Use a polyfill to provide these for older browsers.

What it means

relay-runtime requires Map, Set, Promise, and Object.assign at load time. This dev-mode check runs when the module is imported and throws immediately if any of these ES6 built-ins are missing, telling you to polyfill them for older browsers.

Source

Thrown at packages/relay-runtime/index.js:264

  UpdatableFragment,
  UpdatableQuery,
  Variables,
  VariablesOf,
} from './util/RelayRuntimeTypes';
export type {Local3DPayload} from './util/createPayloadFor3DField';
export type {Direction} from './util/getPaginationVariables';
export type {RequestIdentifier} from './util/getRequestIdentifier';
export type {ResolverFunction} from './util/ReaderNode';
export type {IdOf, RelayResolverValue, Result} from './experimental';

// As early as possible, check for the existence of the JavaScript globals which
// Relay Runtime relies upon, and produce a clear message if they do not exist.
if (__DEV__) {
  const mapStr = typeof Map !== 'function' ? 'Map' : null;
  const setStr = typeof Set !== 'function' ? 'Set' : null;
  const promiseStr = typeof Promise !== 'function' ? 'Promise' : null;
  const objStr = typeof Object.assign !== 'function' ? 'Object.assign' : null;
  if (mapStr || setStr || promiseStr || objStr) {
    throw new Error(
      `relay-runtime requires ${[mapStr, setStr, promiseStr, objStr]
        .filter(Boolean)
        .join(', and ')} to exist. ` +
        'Use a polyfill to provide these for older browsers.',
    );
  }
}

const {
  areEqualSelectors,
  createNormalizationSelector,
  createReaderSelector,
  getDataIDsFromFragment,
  getDataIDsFromObject,
  getPluralSelector,
  getSelector,
  getSelectorsFromObject,

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Add core-js polyfills at app entry: import 'core-js/stable' or targeted imports of Map, Set, Promise, and Object.assign
  2. Update browserslist targets (e.g. "> 0.25%, not dead") so the bundler's useBuiltIns automatically includes needed polyfills
  3. Drop IE11/legacy support if possible so no polyfill layer is needed
  4. Verify Node version is >= modern requirement if the error appears server-side

Example fix

// before (app entry)
import React from 'react';
// after
import 'core-js/stable';
import React from 'react';
Defensive patterns

Strategy: fallback

Validate before calling

const missing = [
  typeof Map !== 'function' && 'Map',
  typeof Set !== 'function' && 'Set',
  typeof Promise !== 'function' && 'Promise',
  typeof Object.assign !== 'function' && 'Object.assign',
].filter(Boolean);
if (missing.length) console.warn('Polyfills required:', missing.join(', '));

Try / catch

try {
  const {Environment} = require('relay-runtime');
} catch (e) {
  if (/requires .* to exist/.test(e.message)) {
    await import('core-js/stable');
    // re-attempt import or reload
  }
}

Prevention

When it happens

Trigger: Importing relay-runtime (or react-relay) into a bundle executed by an environment lacking ES6 globals: IE11, old Android WebView, legacy Node (<4), or a bundle that ships raw untranspiled code to old targets without core-js polyfills.

Common situations: Supporting legacy browsers with babel but no polyfill for built-ins (only syntax transform); targeted bundler config (browserslist) set to ancient browsers; embedding Relay in a sandboxed/legacy JS runtime.


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/584d4e6a7b776456. Report an issue: GitHub.