dgraph-io/dgraph · error

Tokenizer: %s isn't valid for predicate: %s of type: %s

Error message

Tokenizer: %s isn't valid for predicate: %s of type: %s

What it means

Tokenizers are type-specific: a tokenizer's associated type (e.g. hash→string, int→int) must equal the predicate's schema type. resolveTokenizers converts the tokenizer name to its type and rejects the update if it doesn't match the predicate type, naming the tokenizer, predicate, and type.

Source

Thrown at schema/parse.go:449

				"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 {
				return errors.Errorf("Tokenizer: %s isn't valid for predicate: %s of type: %s",
					tokenizer.Name(), x.ParseAttr(schema.Predicate), typ.Name())
			}
			if _, ok := seen[tokenizer.Name()]; !ok {
				seen[tokenizer.Name()] = true
			} else {
				return errors.Errorf("Duplicate tokenizers present for attr %s",
					x.ParseAttr(schema.Predicate))
			}
			if tokenizer.IsSortable() {
				if seenSortableTok {
					return errors.Errorf("More than one sortable index encountered for: %v",
						schema.Predicate)
				}
				seenSortableTok = true
			}
		}
	}
	return nil

View on GitHub (pinned to 759e242be6)

Solutions

  1. Match tokenizer to type: string → hash/exact/term/fulltext/trigram; int → int; float → float; datetime → datetime (optionally with year/month/day/hour tz variants); bool/geo → default/geo respectively.
  2. Remove explicit tokenizers from non-string scalars: `count: int @index(int) .` is correct; `@index(term)` is not.
  3. Re-apply the schema update after fixing.

Example fix

// before
count: int @index(term) .
// after
count: int @index(int) .
Defensive patterns

Strategy: validation

Validate before calling

const TOK_TYPE = {hash:'string',exact:'string',term:'string',fulltext:'string',trigram:'string',int:'int',float:'float',datetime:'datetime',geo:'geo',default:'bool'};
function validateTypeMatch(predType, tokenizers) {
  for (const t of tokenizers) {
    if (TOK_TYPE[t] && TOK_TYPE[t] !== predType) {
      throw new Error(`tokenizer ${t} invalid for type ${predType}`);
    }
  }
}

Try / catch

try {
  await dgraph.Alter(ctx, op);
} catch (e) {
  if (String(e).includes("isn't valid for predicate")) {
    // fix tokenizer/type pairing and re-apply
  }
  throw e;
}

Prevention

When it happens

Trigger: Mixing types and tokenizers: `count: int @index(term)`, `name: string @index(int)`, or `when: datetime @index(hash)` in a schema alteration.

Common situations: Copy-pasting schema lines between predicates of different types; bulk migrations generating @index directives without adjusting per type; confusion that string tokenizers apply to scalar types (int/float/bool/datetime take no explicit string tokenizers).

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