gatsbyjs/gatsby · critical
Types implementing queryable interfaces must also implement
Error message
Types implementing queryable interfaces must also implement the `Node` interface. Check the type definition of ${incorrectTypes}. What it means
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.
Source
Thrown at packages/gatsby/src/schema/schema.js:1405
queryableInterfaces.add(type.getTypeName())
}
})
const incorrectTypes = new Set()
schemaComposer.forEach(type => {
if (type instanceof ObjectTypeComposer) {
const interfaces = type.getInterfaces()
if (
interfaces.some(iface =>
queryableInterfaces.has(iface.getTypeName())
) &&
!type.hasInterface(`Node`)
) {
incorrectTypes.add(type.getTypeName())
}
}
})
if (incorrectTypes.size) {
report.panic(
`Types implementing queryable interfaces must also implement the \`Node\` ` +
`interface. Check the type definition of ` +
`${Array.from(incorrectTypes)
.map(t => `\`${t}\``)
.join(`, `)}.`
)
}
}
const mergeFields = ({ typeComposer, fields }) =>
Object.entries(fields).forEach(([fieldName, fieldConfig]) => {
if (typeComposer.hasField(fieldName)) {
typeComposer.extendField(fieldName, fieldConfig)
} else {
typeComposer.setField(fieldName, fieldConfig)
}
})
View on GitHub (pinned to 8b06340921)
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.
Example fix
// before
type MyType implements MyQueryableInterface {
id: ID!
}
// after
type MyType implements MyQueryableInterface & Node {
id: ID!
} Defensive patterns
Strategy: validation
Validate before calling
// Check that types implementing queryable interfaces also implement Node
function validateQueryableInterfaces(typeDefs, queryableInterfaceNames) {
const issues = []
for (const iface of queryableInterfaceNames) {
const re = new RegExp('type\\s+(\\w+)\\s+implements\\s+[^{]*' + iface + '[^{]*\\{', 'g')
let match
while ((match = re.exec(typeDefs))) {
const implBlock = typeDefs.slice(match.index, match.index + 200)
if (!/Node/.test(implBlock)) {
issues.push(match[1] + ' implements ' + iface + ' but not Node')
}
}
}
return issues
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Building schema failed
- Interfaces with the `nodeInterface` extension must have a fi
- stringifiedErrors
- Can't determine type for "${value}" in \`${selector}\`.
- Expected non-null field value.
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/e259339426db3e36.
Report an issue: GitHub.