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

  1. Add a tokenizer to the predicate, e.g. 'name: string @index(hash)' or set s.Tokenizer = []string{"hash"} in the pb.SchemaUpdate.
  2. If indexing is not actually needed, drop the @index directive entirely (leave Directive unset / remove @index from the schema line).
  3. For vector predicates, supply a vector index spec (e.g. @index(hnsw(metric:"euclidean"))) so HasTokenizerOrVectorIndexSpec passes.
  4. 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

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


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/e96dacdeee0a769c. Report an issue: GitHub.