facebook/relay · error

BabelPluginRelay: Expected plugin context to include "types"

Error message

BabelPluginRelay: Expected plugin context to include "types", but got:${String(context)}

What it means

BabelPluginRelay is a Babel plugin, and Babel passes a plugin context object containing the compiler 'types' builder (t) used to construct AST nodes. The plugin destructures context.types and throws this error if it is falsy. This means the plugin was invoked outside a proper Babel plugin environment, or the Babel version's context shape is incompatible with what the plugin expects.

Source

Thrown at packages/babel-plugin-relay/BabelPluginRelay.js:77

  opts?: RelayPluginOptions,
  ...
};

/**
 * Using babel-plugin-relay with only the modern runtime?
 *
 *     {
 *       plugins: [
 *         "relay"
 *       ]
 *     }
 */
module.exports = function BabelPluginRelay(context: {
  types: $FlowFixMe,
  ...
}): any {
  const {types: t} = context;
  if (!t) {
    throw new Error(
      'BabelPluginRelay: Expected plugin context to include "types", but got:' +
        String(context),
    );
  }

  const visitor = {
    TaggedTemplateExpression(path: any, state: BabelState) {
      // Convert graphql`` literals
      const ast = getValidGraphQLTag(path);
      if (ast) {
        compileGraphQLTag(t, path, state, ast);
        return;
      }
    },
  };

  return {

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Verify the plugin is declared in babel config as 'babel-plugin-relay' or 'relay' and not invoked manually with a custom context object
  2. Check Babel version compatibility: ensure @babel/core is a supported version (>=7) and babel-plugin-relay matches your relay version
  3. Remove any wrapper code that calls BabelPluginRelay() directly with a non-standard context
  4. Reinstall node_modules to rule out duplicate/mismatched babel packages

Example fix

// before (manual invocation)
const plugin = require('babel-plugin-relay');
plugin({ /* stub context without types */ });

// after (proper babel config)
// babel.config.js
module.exports = { plugins: ['babel-plugin-relay'] };
Defensive patterns

Strategy: validation

Validate before calling

function assertBabelPluginContext(context) {
  if (!context || typeof context !== 'object' || !context.types) {
    throw new Error(
      'babel-plugin-relay requires a Babel plugin context with `types`',
    );
  }
  return context;
}

Type guard

const hasTypes = (context) =>
  typeof context === 'object' && context !== null && !!context.types;

Prevention

When it happens

Trigger: Babel loads the plugin without a valid plugin context (e.g. context is undefined/null or an object without a 'types' property), such as when the plugin is misconfigured, invoked programmatically with a hand-made context, or run under an incompatible Babel version that does not supply 'types' in the plugin state.

Common situations: Manually calling the plugin in a script with a stub context; using an ancient/newer Babel major version with an incompatible babel-plugin-relay; double-wrapping the plugin so it receives the wrong argument; registering the plugin in a non-Babel transform pipeline (e.g. a bundler loader that calls plugins directly).

Related errors


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