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
- Replace the type-system definition with a supported construct: a fragment (fragment X on Type {...}) or an operation (query/mutation/subscription)
- Move SDL/schema definitions out of component code into a separate .graphql schema file
- 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
- Never put SDL/type-system definitions (scalar, schema, directive) in graphql`` tags
- Start every tag's body with fragment/query/mutation/subscription
- Keep schema definitions in a separate .graphql file consumed by the Relay compiler
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
- BabelPluginRelay: Expected exactly one definition per graphq
- GraphQL operations and fragments must contain names
- BabelPluginRelay: Substitutions are not allowed in graphql f
- BabelPluginRelay: Unexpected empty graphql tag.
- BabelPluginRelay: Expected plugin context to include "types"
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/49cff6e8f949694d.
Report an issue: GitHub.