gatsbyjs/gatsby · error · StringInterpolationNotAllowedError

BabelPluginRemoveGraphQLQueries: String interpolations are n

Error message

BabelPluginRemoveGraphQLQueries: String interpolations are not allowed in graphql fragments. Included fragments should be referenced as `...MyModule_foo`.

What it means

Thrown by `StringInterpolationNotAllowedError` in babel-plugin-remove-graphql-queries (index.ts:256). The plugin extracts graphql template literals; if the template has more than one `quasi` (`quasis.length !== 1`) it means the developer used `${...}` interpolation inside the tag. Gatsby pre-compiles queries statically, so runtime interpolation is forbidden — fragments must be referenced via the `...Name` spread syntax and the graphql tag must contain only literal text.

Source

Thrown at packages/babel-plugin-remove-graphql-queries/src/index.ts:256

  }
  if (importPath.isIdentifier()) {
    removeVariableDeclaration(importPath)
  }
}

function getGraphQLTag(
  path: NodePath<TaggedTemplateExpression>,
  tagName: string = `graphql`
): IGraphQLTag {
  const tag: NodePath = path.get(`tag`) as NodePath
  const isGlobal: boolean = isGlobalIdentifier(tag, tagName)

  if (!isGlobal && !isGraphqlTag(tag, tagName)) return {} as IGraphQLTag

  const quasis: Array<TemplateElement> = path.node.quasi.quasis

  if (quasis.length !== 1) {
    throw new StringInterpolationNotAllowedError(
      quasis[0].loc?.end,
      quasis[1].loc?.start
    )
  }

  const text: string = quasis[0].value.raw
  const normalizedText: string = graphql.stripIgnoredCharacters(text)

  const hash: number = murmurhash(normalizedText, 0)
  const location = quasis[0].loc as SourceLocation | null

  try {
    const ast = graphql.parse(text)

    if (ast.definitions.length === 0) {
      throw new EmptyGraphQLTagError(location)
    }
    return { ast, text: normalizedText, hash, isGlobal }

View on GitHub (pinned to 8b06340921)

Solutions

  1. Replace `${MyFragment}` with the fragment spread `...MyFragment` inside the literal.
  2. Ensure the graphql tag contains only literal text — move any dynamic parts out of the query.
  3. Define the fragment with `graphql`fragment X on Y { ... }`` and reference it via spread.

Example fix

// before
const query = graphql`
  query {
    ${userFragment}
  }
`

// after
const query = graphql`
  query {
    ...UserFields
  }
`
const frag = graphql`
  fragment UserFields on User { id name }
`
Defensive patterns

Strategy: validation

Validate before calling

function graphqlTagHasNoInterpolation(quasis) {
  return quasis.length === 1
}

Type guard

function isPureTemplateLiteral(node) {
  return node.quasis.length === 1 && node.expressions.length === 0
}

Try / catch

try {
  getGraphQLTag(path)
} catch (e) {
  if (e instanceof StringInterpolationNotAllowedError) { /* convert ${x} -> ...X spread */ }
}

Prevention

When it happens

Trigger: Writing `graphql`query { ${field} }``; interpolating a fragment string into a graphql tag; building a query dynamically with template expressions; mistakenly using `${variable}` where a fragment spread was intended.

Common situations: Trying to share query fragments by string concatenation; porting Apollo Client code that used interpolation; refactoring and accidentally leaving a `${}` inside a graphql tag.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/5373a4e109761f98. Report an issue: GitHub.