dgraph-io/dgraph · error
Tokenizer must be specified while indexing a predicate: %+v
Error message
Tokenizer must be specified while indexing a predicate: %+v
What it means
checkSchema in worker/mutation.go validates schema mutations before proposing them to the cluster. When a schema update carries Directive == SchemaUpdate_INDEX (i.e. the predicate is being (re)indexed), at least one tokenizer (or a vector index spec) must also be supplied. Dgraph refuses an index directive with no tokenizer because it cannot build an index without knowing how to tokenize values.
Source
Thrown at worker/mutation.go:394
}
return false
}
func checkSchema(s *pb.SchemaUpdate) error {
if s == nil {
return errors.Errorf("Nil schema")
}
if x.ParseAttr(s.Predicate) == "" {
return errors.Errorf("No predicate specified in schema mutation")
}
if x.IsInternalPredicate(s.Predicate) {
return errors.Errorf("Cannot create user-defined predicate with internal name %s",
x.ParseAttr(s.Predicate))
}
if s.Directive == pb.SchemaUpdate_INDEX && !schema.HasTokenizerOrVectorIndexSpec(s) {
return errors.Errorf("Tokenizer must be specified while indexing a predicate: %+v", s)
}
if schema.HasTokenizerOrVectorIndexSpec(s) && s.Directive != pb.SchemaUpdate_INDEX {
return errors.Errorf("Directive must be SchemaUpdate_INDEX when a tokenizer is specified")
}
typ := types.TypeID(s.ValueType)
if typ == types.UidID && s.Directive == pb.SchemaUpdate_INDEX {
// index on uid type
return errors.Errorf("Index not allowed on predicate of type uid on predicate %s",
x.ParseAttr(s.Predicate))
} else if typ != types.UidID && s.Directive == pb.SchemaUpdate_REVERSE {
// reverse on non-uid type
return errors.Errorf("Cannot reverse for non-uid type on predicate %s",
x.ParseAttr(s.Predicate))
}
// If schema update has upsert directive, it should have index directive.View on GitHub (pinned to 759e242be6)
Solutions
- Add a tokenizer to the predicate, e.g. 'name: string @index(hash)' or set s.Tokenizer = []string{"hash"} in the pb.SchemaUpdate.
- If indexing is not actually needed, drop the @index directive entirely (leave Directive unset / remove @index from the schema line).
- For vector predicates, supply a vector index spec (e.g. @index(hnsw(metric:"euclidean"))) so HasTokenizerOrVectorIndexSpec passes.
- Validate the schema locally with schema.Parse or a dry run before proposing the mutation.
Example fix
// before name: string @index . // after name: string @index(hash) .
Defensive patterns
Strategy: validation
Validate before calling
func validateIndexDirective(s *pb.SchemaUpdate) error {
if s.Directive == pb.SchemaUpdate_INDEX && !schema.HasTokenizerOrVectorIndexSpec(s) {
return fmt.Errorf("predicate %s: @index requires a tokenizer", s.Predicate)
}
return nil
} Type guard
func hasTokenizer(s *pb.SchemaUpdate) bool {
return len(s.Tokenizer) > 0
} Try / catch
err := dgraph.Alter(ctx, op)
if err != nil && strings.Contains(err.Error(), "Tokenizer must be specified") {
// fix schema: add tokenizer or drop @index, then retry
} Prevention
- Always pair @index with a tokenizer in parentheses
- Lint DQL schema files for @index without tokenizer
- Unit-test generated schemas against checkSchema
When it happens
Trigger: Sending a schema (via ALTER / client.Alter / runSchemaMutation / createSchema) with '@index' on a predicate but no tokenizer arguments, e.g. 'name: string @index .' without the tokenizer, or building a pb.SchemaUpdate with Directive: pb.SchemaUpdate_INDEX and an empty Tokenizer slice and no vector index spec.
Common situations: Hand-written DQL schema blocks where '@index' is written without parentheses/tokenizer; programmatic schema generation that sets Directive but forgets to append Tokenizers; copying a schema and stripping tokenizers while keeping @index; upgrading from a schema that had a default tokenizer assumption.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Require type of tokenizer for pred: %s of type: %s for index
- Tokenizers present without indexing on attr %s
- failed to enrich schema
- Directive must be SchemaUpdate_INDEX when a tokenizer is spe
- illegal rune found "%c", expecting {
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/e96dacdeee0a769c.
Report an issue: GitHub.