dgraph-io/dgraph · error
Field in type definition cannot have tokenizers
Error message
Field in type definition cannot have tokenizers
What it means
typeSanityCheck rejects type-definition fields that specify tokenizers. Tokenizers (hash, exact, term, fulltext, etc.) control indexing at the predicate level; a type definition only lists which predicates belong to the type, so attaching tokenizers there is invalid and the whole type update is refused.
Source
Thrown at worker/mutation.go:835
// typeSanityCheck performs basic sanity checks on the given type update.
func typeSanityCheck(t *pb.TypeUpdate) error {
for _, field := range t.Fields {
if x.ParseAttr(field.Predicate) == "" {
return errors.Errorf("Field in type definition must have a name")
}
if field.ValueType == pb.Posting_OBJECT && field.ObjectTypeName == "" {
return errors.Errorf(
"Field with value type OBJECT must specify the name of the object type")
}
if field.Directive != pb.SchemaUpdate_NONE {
return errors.Errorf("Field in type definition cannot have a directive")
}
if len(field.Tokenizer) > 0 {
return errors.Errorf("Field in type definition cannot have tokenizers")
}
}
return nil
}
// CommitOverNetwork makes a proxy call to Zero to commit or abort a transaction.
func CommitOverNetwork(ctx context.Context, tc *api.TxnContext) (uint64, error) {
ctx, span := otel.Tracer("").Start(ctx, "worker.CommitOverNetwork")
defer span.End()
clientDiscard := false
if tc.Aborted {
// The client called Discard
ostats.Record(ctx, x.TxnDiscards.M(1))
clientDiscard = true
}
View on GitHub (pinned to 759e242be6)
Solutions
- Strip tokenizers from the type block and declare them on the predicate line instead: `name: string @index(hash) .`
- Ensure schema-generation code creates separate pb.SchemaUpdate entries for predicates (with Tokenizer) and types (with Tokenizer empty)
- Re-send the alter request after separating predicate schema from type definitions
Example fix
// before
type Person {
name @index(hash)
}
// after
name: string @index(hash) .
type Person {
name
} Defensive patterns
Strategy: validation
Validate before calling
for _, f := range typeDef.Fields {
if len(f.Tokenizer) > 0 {
return fmt.Errorf("field %q: tokenizers must be declared on the predicate", f.Predicate)
}
} Type guard
func fieldHasNoTokenizer(f *pb.SchemaUpdate) bool {
return len(f.Tokenizer) == 0
} Prevention
- Declare tokenizers only with @index on predicate lines
- Zero out Tokenizer when transforming predicate entries into type fields
- Review generated schema for stray @index inside type blocks
When it happens
Trigger: An alter/schema request where a field inside a `type` block has a non-empty Tokenizer array — usually because schema-building code copies pb.SchemaUpdate entries built for predicates (which carry tokenizers) into type definitions.
Common situations: Reusing one schema JSON/struct for both predicate and type definitions; migrating from predicate-centric tooling and forgetting tokenizers are not part of type blocks; hand-written DQL placing tokenizers inside type blocks.
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
- Require type of tokenizer for pred: %s of type: %s for index
- Tokenizers present without indexing on attr %s
- Invalid tokenizer %s
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/f100fbeac5ee7258.
Report an issue: GitHub.