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 nilView on GitHub (pinned to 759e242be6)
Solutions
- 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.
- Remove explicit tokenizers from non-string scalars: `count: int @index(int) .` is correct; `@index(term)` is not.
- 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
- Pair tokenizers to predicate types: string→hash/exact/term/fulltext/trigram; int→int; float→float; datetime→datetime variants
- Never apply string tokenizers to scalar types
- Keep a schema-typing table in migration code
- Run schema Alter against a test cluster first
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
- illegal rune found "%c", expecting {
- Malformed JSON
- UID must be present and non-zero while deleting edges
- facet value can only be string/number/bool
- facets format should be of type map for scalarlist predicate
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/92c8f1f1460d5d52.
Report an issue: GitHub.