{"record":{"id":"66a7871259ec08c4","repo":"facebook/relay","slug":"babelpluginrelay-expected-exactly-one-definition","errorCode":null,"errorMessage":"BabelPluginRelay: Expected exactly one definition per graphql tag.","messagePattern":"BabelPluginRelay: Expected exactly one definition per graphql tag\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/babel-plugin-relay/compileGraphQLTag.js","lineNumber":54,"sourceCode":" * cross-platform compatibility.\n */\nfunction posixifyPath(path: string): string {\n  // $FlowFixMe[cannot-resolve-name]\n  return process.platform === 'win32' ? path.replace(/\\\\/g, '/') : path;\n}\n\n/**\n * Given a graphql`` tagged template literal, replace it with the appropriate\n * runtime artifact.\n */\nfunction compileGraphQLTag(\n  t: $FlowFixMe,\n  path: Object,\n  state: BabelState,\n  ast: DocumentNode,\n): void {\n  if (ast.definitions.length !== 1) {\n    throw new Error(\n      'BabelPluginRelay: Expected exactly one definition per graphql tag.',\n    );\n  }\n  const definition = ast.definitions[0];\n  if (\n    definition.kind !== 'FragmentDefinition' &&\n    definition.kind !== 'OperationDefinition'\n  ) {\n    throw new Error(\n      'BabelPluginRelay: Expected a fragment, mutation, query, or ' +\n        'subscription, got `' +\n        definition.kind +\n        '`.',\n    );\n  }\n\n  const eagerEsModules = state.opts?.eagerEsModules ?? true;\n  const isHasteMode = state.opts?.jsModuleFormat === 'haste';","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/babel-plugin-relay/compileGraphQLTag.js#L36-L72","documentation":"A graphql`` tagged template in Relay must contain exactly one GraphQL definition (one fragment, query, mutation, or subscription). The plugin parses the template's text into a DocumentNode and throws when ast.definitions.length !== 1. Multiple definitions in a single graphql tag are not supported because each tag compiles to exactly one artifact.","triggerScenarios":"A graphql`` template literal whose text parses to two or more definitions, e.g. graphql`fragment F on T {...} fragment G on U {...}`, or a tag that accidentally includes multiple statements separated by whitespace/comments.","commonSituations":"Copy-pasting several fragments into one tag; concatenating queries when refactoring; tooling that merges GraphQL documents into a single template literal.","solutions":["Split the definitions into separate graphql`` tags, one per fragment/operation","Check the template literal for stray text or copied extra definitions and delete them","If composing, reference other fragments via spread syntax `...OtherFragment_name` inside one fragment instead of declaring them together"],"exampleFix":"// before\nconst query = graphql`\n  fragment A on User { id }\n  fragment B on User { name }\n`;\n\n// after\nconst fragmentA = graphql`fragment A on User { id }`;\nconst fragmentB = graphql`fragment B on User { name }`;","handlingStrategy":"validation","validationCode":"function assertSingleDefinition(text) {\n  const ast = require('graphql').parse(text);\n  if (ast.definitions.length !== 1) {\n    throw new Error(`graphql tag must contain exactly one definition, got ${ast.definitions.length}`);\n  }\n}","typeGuard":"const hasSingleDefinition = (ast) =>\n  ast && Array.isArray(ast.definitions) && ast.definitions.length === 1;","tryCatchPattern":null,"preventionTips":["Keep one operation/fragment per graphql`` tag","Use a lint rule (e.g. eslint-plugin-graphql / relay compiler in CI) to catch multi-definition tags","Reference shared fields via fragment spreads rather than combining definitions"],"tags":["babel","build-time","graphql","relay"],"backgroundTag":"invalid-graphql-tag","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}