gatsbyjs/gatsby · critical

Interfaces with the `nodeInterface` extension must have a fi

Error message

Interfaces with the `nodeInterface` extension must have a field `id` of type `ID!`. Check the type definition of `${typeComposer.getTypeName()}`.

What it means

When a GraphQL interface type has the nodeInterface extension set, Gatsby requires it to declare a field named `id` of type `ID!` (non-null ID). This is the contract that allows the interface to participate in Gatsby's global node identification system. The panic fires when hasField('id') is false or the field type is not exactly ID!.

Source

Thrown at packages/gatsby/src/schema/schema.js:515

  typeComposer,
  extensions = {},
  plugin,
  createdFrom,
}) => {
  typeComposer.setExtension(`createdFrom`, createdFrom)
  typeComposer.setExtension(`plugin`, plugin ? plugin.name : null)
  typeComposer.extendExtensions(extensions)

  if (
    typeComposer instanceof InterfaceTypeComposer &&
    isNodeInterface(typeComposer)
  ) {
    const hasCorrectIdField =
      typeComposer.hasField(`id`) &&
      typeComposer.getFieldType(`id`).toString() === `ID!`

    if (!hasCorrectIdField) {
      report.panic(
        `Interfaces with the \`nodeInterface\` extension must have a field ` +
          `\`id\` of type \`ID!\`. Check the type definition of ` +
          `\`${typeComposer.getTypeName()}\`.`
      )
    }
  }

  if (
    typeComposer instanceof ObjectTypeComposer ||
    typeComposer instanceof InterfaceTypeComposer ||
    typeComposer instanceof InputTypeComposer
  ) {
    typeComposer.getFieldNames().forEach(fieldName => {
      typeComposer.setFieldExtension(fieldName, `createdFrom`, createdFrom)
      typeComposer.setFieldExtension(
        fieldName,
        `plugin`,
        plugin ? plugin.name : null

View on GitHub (pinned to 8b06340921)

Solutions

  1. Add `id: ID!` to the interface type definition that has the @nodeInterface extension.
  2. If the field exists, ensure its type is exactly ID! not ID -- change nullable to non-null.
  3. If you did not intend this interface to be a node interface, remove the @nodeInterface extension / nodeInterface extension setting.

Example fix

// before
interface MyInterface @nodeInterface {
  name: String
}

// after
interface MyInterface @nodeInterface {
  id: ID!
  name: String
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate node interface has id: ID!
function validateNodeInterface(typeDef) {
  if (!/@nodeInterface/.test(typeDef)) return true
  const hasIdField = /\bid\s*:\s*ID!/.test(typeDef)
  return hasIdField
}

if (!validateNodeInterface(myTypeDef)) {
  throw new Error('nodeInterface types must have id: ID!')
}

Prevention

When it happens

Trigger: Defining an interface type with the @nodeInterface extension (or programmatically setting the nodeInterface extension) that either omits the id field, makes it nullable (ID), or names the field something other than id.

Common situations: A plugin or gatsby-node.js uses createTypes with `interface NodeInterface @nodeInterface { ... }` but forgets the `id: ID!` field. Or the id field is declared as ID (nullable) instead of ID!.

Related errors


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