dgraph-io/dgraph · error

Require type of tokenizer for pred: %s of type: %s for index

Error message

Require type of tokenizer for pred: %s of type: %s for indexing.

What it means

If a predicate is marked @index (Directive == SchemaUpdate_INDEX) but no tokenizers (or vector index spec) are provided, resolveTokenizers cannot build the index and returns this error naming the predicate and its type. In Dgraph, indexed string/other predicates require at least one tokenizer (hash, exact, term, fulltext, etc.) so the index knows how to encode values.

Source

Thrown at schema/parse.go:430

// resolveTokenizers resolves default tokenizers and verifies tokenizers definitions.
func resolveTokenizers(updates []*pb.SchemaUpdate) error {
	for _, schema := range updates {
		typ := types.TypeID(schema.ValueType)

		if (typ == types.UidID || typ == types.DefaultID || typ == types.PasswordID) &&
			schema.Directive == pb.SchemaUpdate_INDEX {
			return errors.Errorf("Indexing not allowed on predicate %s of type %s",
				x.ParseAttr(schema.Predicate), typ.Name())
		}

		if typ == types.UidID {
			continue
		}

		if !HasTokenizerOrVectorIndexSpec(schema) &&
			schema.Directive == pb.SchemaUpdate_INDEX {
			return errors.Errorf(
				"Require type of tokenizer for pred: %s of type: %s for indexing.",
				schema.Predicate, typ.Name())
		} else if HasTokenizerOrVectorIndexSpec(schema) &&
			schema.Directive != pb.SchemaUpdate_INDEX {
			return errors.Errorf("Tokenizers present without indexing on attr %s",
				x.ParseAttr(schema.Predicate))
		}
		// check for valid tokenizer types and duplicates
		var seen = make(map[string]bool)
		var seenSortableTok bool
		for _, t := range schema.Tokenizer {
			tokenizer, has := tok.GetTokenizer(t)
			if !has {
				return errors.Errorf("Invalid tokenizer %s", t)
			}
			tokenizerType, ok := types.TypeForName(tokenizer.Type())
			x.AssertTrue(ok) // Type is validated during tokenizer loading.
			if tokenizerType != typ {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Add a tokenizer: e.g. `pred: string @index(hash) .` or `@index(term, fulltext)` for strings, `@index(int)`/`@index(float)`/`@index(datetime)` for others.
  2. For vector embeddings, supply the vector index specification (metric/dimension) instead of / in addition to tokenizers.
  3. Drop the @index directive if you don't need to filter/sort on the predicate.
  4. Re-apply the schema alteration.

Example fix

// before
name: string @index .
// after
name: string @index(hash) .
Defensive patterns

Strategy: validation

Validate before calling

function requireTokenizer(schemaLine) {
  const m = schemaLine.match(/@(index)\s*(\([^)]*\))?\s*\./);
  if (m && m[1] === 'index' && !m[2]) {
    throw new Error('indexed predicate needs a tokenizer: @index(hash) etc.');
  }
}

Try / catch

try {
  await dgraph.Alter(ctx, op);
} catch (e) {
  if (String(e).includes('Require type of tokenizer')) {
    // re-send SchemaUpdate with Tokenizer populated
  }
  throw e;
}

Prevention

When it happens

Trigger: Altering schema with `pred: string @index .` (no tokenizer list) or an API SchemaUpdate with Directive=INDEX and empty Tokenizer array and no vector index spec.

Common situations: Hand-written DQL schema where the tokenizer list was forgotten; programmatic schema clients (go/pydgraph) building SchemaUpdate structs with Directive set but Tokenizer nil; migrations generated from other DBs that only say 'indexed: true'.

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/f4adb94705512c3d. Report an issue: GitHub.