dgraph-io/dgraph · error
type %s doesn't have a key Directive
Error message
type %s doesn't have a key Directive
What it means
For federation entity resolution, the type named by __typename must declare an @key directive identifying its primary key field(s). This error is thrown when the type exists in the schema but has no @key directive, so the subgraph cannot resolve the entity from the representation.
Source
Thrown at graphql/schema/wrappers.go:1733
if len(representations) == 0 {
return nil, fmt.Errorf("expecting at least one item in `representations` argument")
}
representation, ok := representations[0].(map[string]interface{})
if !ok {
return nil, fmt.Errorf("error parsing %dth item in the `_representations` argument", 0)
}
typename, ok := representation[Typename].(string)
if !ok {
return nil, fmt.Errorf("unable to extract __typename from %dth item in the"+
" `_representations` argument", 0)
}
typ := q.op.inSchema.schema.Types[typename]
if typ == nil {
return nil, fmt.Errorf("type %s not found in the schema", typename)
}
keyDir := typ.Directives.ForName(apolloKeyDirective)
if keyDir == nil {
return nil, fmt.Errorf("type %s doesn't have a key Directive", typename)
}
keyFldName := keyDir.Arguments[0].Value.Raw
// initialize the struct to return
entityReprs := &EntityRepresentations{
TypeDefn: &astType{
typ: &ast.Type{NamedType: typename},
inSchema: q.op.inSchema,
dgraphPredicate: q.op.inSchema.dgraphPredicate,
},
KeyVals: make([]interface{}, 0, len(representations)),
KeyValToRepresentation: make(map[string]map[string]interface{}),
}
entityReprs.KeyField = entityReprs.TypeDefn.Field(keyFldName)
// iterate over all the representations and parse
for i, rep := range representations {
representation, ok = rep.(map[string]interface{})View on GitHub (pinned to 759e242be6)
Solutions
- Add a @key directive to the type: `type Product @key(fields: "id") { id: ID! ... }`
- Ensure the federation @key directive is declared/imported in the schema
- Republish the supergraph after adding the directive
Example fix
// before
type Product { id: ID! name: String }
// after
type Product @key(fields: "id") { id: ID! name: String } Defensive patterns
Strategy: validation
Validate before calling
// before deploying, assert every entity type has @key
for _, t := range schema.Types {
if isEntityType(t) && t.Directives.ForName("key") == nil {
return fmt.Errorf("type %s missing @key", t.Name)
}
} Type guard
func hasKeyDirective(t *ast.Definition) bool {
return t != nil && t.Directives.ForName("key") != nil
} Try / catch
entity, err := q.RepresentationsArg()
if err != nil && strings.Contains(err.Error(), "key Directive") {
return nil, fmt.Errorf("type not resolvable as federated entity: %w", err)
} Prevention
- Annotate every federated entity type with @key(fields: ...) at schema authoring time
- Declare the federation @key directive in the schema (or import the federation spec)
- Republish the supergraph after adding entities so the gateway knows the keys
When it happens
Trigger: _entities query for a type defined in the subgraph schema without `@key(fields: "...")` (or `directive @key` from the federation spec) — e.g. an entity type missing federation annotations.
Common situations: Adding a type to a federation subgraph but forgetting the @key directive; converting a plain type into an entity without updating the schema; federation spec version mismatch (e.g. missing `extend type ... @key`).
Related errors
- type %s not found in the schema
- encountered an XID %s with %s that isn'tallowed as Xid
- Unable to find the type %s on the remote schema
- Not resolving subscription because schema doesn't have any f
- while parsing GraphQL schema
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/528682e757e26318.
Report an issue: GitHub.