{"record":{"id":"e259339426db3e36","repo":"gatsbyjs/gatsby","slug":"types-implementing-queryable-interfaces-must-also","errorCode":null,"errorMessage":"Types implementing queryable interfaces must also implement the `Node` interface. Check the type definition of ${incorrectTypes}.","messagePattern":"Types implementing queryable interfaces must also implement the `Node` interface\\. Check the type definition of (.+?)\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/gatsby/src/schema/schema.js","lineNumber":1405,"sourceCode":"      queryableInterfaces.add(type.getTypeName())\n    }\n  })\n  const incorrectTypes = new Set()\n  schemaComposer.forEach(type => {\n    if (type instanceof ObjectTypeComposer) {\n      const interfaces = type.getInterfaces()\n      if (\n        interfaces.some(iface =>\n          queryableInterfaces.has(iface.getTypeName())\n        ) &&\n        !type.hasInterface(`Node`)\n      ) {\n        incorrectTypes.add(type.getTypeName())\n      }\n    }\n  })\n  if (incorrectTypes.size) {\n    report.panic(\n      `Types implementing queryable interfaces must also implement the \\`Node\\` ` +\n        `interface. Check the type definition of ` +\n        `${Array.from(incorrectTypes)\n          .map(t => `\\`${t}\\``)\n          .join(`, `)}.`\n    )\n  }\n}\n\nconst mergeFields = ({ typeComposer, fields }) =>\n  Object.entries(fields).forEach(([fieldName, fieldConfig]) => {\n    if (typeComposer.hasField(fieldName)) {\n      typeComposer.extendField(fieldName, fieldConfig)\n    } else {\n      typeComposer.setField(fieldName, fieldConfig)\n    }\n  })\n","sourceCodeStart":1387,"sourceCodeEnd":1423,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/schema/schema.js#L1387-L1423","documentation":"Gatsby enforces that any object type implementing a queryable interface (one registered as queryable) must also implement the Node interface. Queryable interfaces participate in root-level queries and rely on node identity. The panic lists all violating type names in incorrectTypes.","triggerScenarios":"An object type `implements` a queryable interface (e.g. an interface with the nodeInterface or similar queryable extension) but does not also list Node in its implements clause. The check iterates all types, finds those with a queryable interface but without Node, and panics.","commonSituations":"A plugin defines a queryable interface and a custom type implements it without adding Node. Mixing custom interfaces with node types and forgetting the Node interface requirement. Schema stitching across plugins where one plugin's interface is queryable but consumer types omit Node.","solutions":["Add Node to the implements list of each type listed in the error: `type MyType implements MyInterface & Node { ... }`.","If the interface should not be queryable, remove the queryable extension from the interface definition.","Review all createTypes calls and plugin schema extensions for interface usage on the listed types."],"exampleFix":"// before\ntype MyType implements MyQueryableInterface {\n  id: ID!\n}\n\n// after\ntype MyType implements MyQueryableInterface & Node {\n  id: ID!\n}","handlingStrategy":"validation","validationCode":"// Check that types implementing queryable interfaces also implement Node\nfunction validateQueryableInterfaces(typeDefs, queryableInterfaceNames) {\n  const issues = []\n  for (const iface of queryableInterfaceNames) {\n    const re = new RegExp('type\\\\s+(\\\\w+)\\\\s+implements\\\\s+[^{]*' + iface + '[^{]*\\\\{', 'g')\n    let match\n    while ((match = re.exec(typeDefs))) {\n      const implBlock = typeDefs.slice(match.index, match.index + 200)\n      if (!/Node/.test(implBlock)) {\n        issues.push(match[1] + ' implements ' + iface + ' but not Node')\n      }\n    }\n  }\n  return issues\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When a type implements a queryable interface, always also list Node.","Document which interfaces are queryable in your project conventions.","Review interface usage after schema changes."],"tags":["graphql","schema","node-interface","queryable-interface"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}