dgraph-io/dgraph · error
Tokenizers present without indexing on attr %s
Error message
Tokenizers present without indexing on attr %s
What it means
The inverse of the previous case: the schema update declares tokenizers (or a vector index spec) for a predicate but the directive is not @index. Tokenizers only make sense with an index, so resolveTokenizers rejects the update, naming the attribute. This keeps the stored schema internally consistent.
Source
Thrown at schema/parse.go:435
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 {
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()] = trueView on GitHub (pinned to 759e242be6)
Solutions
- Add the @index directive: `pred: string @index(hash) .`
- Or remove the tokenizer list if the predicate should not be indexed: `pred: string .`
- Check any schema-generation tooling to ensure Directive=SchemaUpdate_INDEX is set whenever Tokenizer is non-empty.
- Re-apply the alteration.
Example fix
// before name: string @hash . // after name: string @index(hash) .
Defensive patterns
Strategy: validation
Validate before calling
function requireIndexWithTokenizers(line) {
const hasTok = /@(hash|exact|term|fulltext|trigram|int|float|datetime|geo|default)\b/.test(line);
const hasIndex = /@index\s*\(/.test(line);
if (hasTok && !hasIndex) throw new Error('tokenizers present without @index: ' + line);
} Try / catch
try {
await dgraph.Alter(ctx, op);
} catch (e) {
if (String(e).includes('Tokenizers present without indexing')) {
// either add @index(...) or drop the tokenizers, then retry
}
throw e;
} Prevention
- Write directives as @index(tokenizer, ...), never bare @hash/@term
- When unindexing a predicate, also clear its Tokenizer list
- Ensure programmatic clients set Directive=INDEX whenever Tokenizer is non-empty
When it happens
Trigger: Altering schema with `pred: string @hash .` (tokenizer given without @index) or a SchemaUpdate with a non-INDEX directive but populated Tokenizer list / vector spec.
Common situations: Typos like writing `@index` wrong or omitting it while listing tokenizers; editing schema by hand and dropping the @index keyword; tooling that sets Tokenizer but forgets Directive; converting a previously indexed predicate back to non-indexed while leaving old 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
- Require type of tokenizer for pred: %s of type: %s for index
- failed to enrich schema
- Tokenizer must be specified while indexing a predicate: %+v
- 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/e379aa54f2a57dc8.
Report an issue: GitHub.