facebook/relay · error

BabelPluginRelay: Expected a fragment, mutation, query, or s

Error message

BabelPluginRelay: Expected a fragment, mutation, query, or subscription, got `${definition.kind}`.

What it means

After ensuring exactly one definition, compileGraphQLTag checks that the definition kind is either FragmentDefinition or OperationDefinition. Anything else (e.g. SchemaDefinition, DirectiveDefinition, or a malformed node from an odd parse) is rejected. Relay's Babel plugin only supports fragments, queries, mutations, and subscriptions inside graphql tags.

Source

Thrown at packages/babel-plugin-relay/compileGraphQLTag.js:61

/**
 * Given a graphql`` tagged template literal, replace it with the appropriate
 * runtime artifact.
 */
function compileGraphQLTag(
  t: $FlowFixMe,
  path: Object,
  state: BabelState,
  ast: DocumentNode,
): void {
  if (ast.definitions.length !== 1) {
    throw new Error(
      'BabelPluginRelay: Expected exactly one definition per graphql tag.',
    );
  }
  const definition = ast.definitions[0];
  if (
    definition.kind !== 'FragmentDefinition' &&
    definition.kind !== 'OperationDefinition'
  ) {
    throw new Error(
      'BabelPluginRelay: Expected a fragment, mutation, query, or ' +
        'subscription, got `' +
        definition.kind +
        '`.',
    );
  }

  const eagerEsModules = state.opts?.eagerEsModules ?? true;
  const isHasteMode = state.opts?.jsModuleFormat === 'haste';
  const isDevVariable = state.opts?.isDevVariableName;
  const artifactDirectory = state.opts?.artifactDirectory;
  const buildCommand = state.opts?.codegenCommand ?? 'relay-compiler';
  // Fallback is 'true'
  const isDevelopment =
    // $FlowFixMe[cannot-resolve-name]
    (process.env.BABEL_ENV || process.env.NODE_ENV) !== 'production';

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Replace the type-system definition with a supported construct: a fragment (fragment X on Type {...}) or an operation (query/mutation/subscription)
  2. Move SDL/schema definitions out of component code into a separate .graphql schema file
  3. Inspect the definition text and confirm the first statement starts with 'fragment', 'query', 'mutation', or 'subscription'

Example fix

// before
const x = graphql`scalar DateTime`;

// after (SDL moved to schema; component uses a fragment)
const x = graphql`fragment DateTimeInfo on Post { publishedAt }`;
Defensive patterns

Strategy: validation

Validate before calling

function assertSupportedKind(text) {
  const { parse } = require('graphql');
  const def = parse(text).definitions[0];
  if (def.kind !== 'FragmentDefinition' && def.kind !== 'OperationDefinition') {
    throw new Error(`Unsupported definition kind in graphql tag: ${def.kind}`);
  }
}

Type guard

const isExecutable = (def) =>
  def && (def.kind === 'FragmentDefinition' || def.kind === 'OperationDefinition');

Prevention

When it happens

Trigger: A graphql`` tag whose single parsed definition is not a fragment or operation — e.g. graphql`schema { query: Query }`, a directive/type-system definition, or text that parses to an unsupported definition kind.

Common situations: Pasting SDL/type-system GraphQL (schema definitions, scalar declarations) into a client graphql`` tag; a typo causing the parser to infer an unexpected kind; using the tag in a .graphql schema-like file.

Related errors


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