{"record":{"id":"92c8f1f1460d5d52","repo":"dgraph-io/dgraph","slug":"tokenizer-s-isn-t-valid-for-predicate-s-of-typ","errorCode":null,"errorMessage":"Tokenizer: %s isn't valid for predicate: %s of type: %s","messagePattern":"Tokenizer: (.+?) isn't valid for predicate: (.+?) of type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/parse.go","lineNumber":449,"sourceCode":"\t\t\t\t\"Require type of tokenizer for pred: %s of type: %s for indexing.\",\n\t\t\t\tschema.Predicate, typ.Name())\n\t\t} else if HasTokenizerOrVectorIndexSpec(schema) &&\n\t\t\tschema.Directive != pb.SchemaUpdate_INDEX {\n\t\t\treturn errors.Errorf(\"Tokenizers present without indexing on attr %s\",\n\t\t\t\tx.ParseAttr(schema.Predicate))\n\t\t}\n\t\t// check for valid tokenizer types and duplicates\n\t\tvar seen = make(map[string]bool)\n\t\tvar seenSortableTok bool\n\t\tfor _, t := range schema.Tokenizer {\n\t\t\ttokenizer, has := tok.GetTokenizer(t)\n\t\t\tif !has {\n\t\t\t\treturn errors.Errorf(\"Invalid tokenizer %s\", t)\n\t\t\t}\n\t\t\ttokenizerType, ok := types.TypeForName(tokenizer.Type())\n\t\t\tx.AssertTrue(ok) // Type is validated during tokenizer loading.\n\t\t\tif tokenizerType != typ {\n\t\t\t\treturn errors.Errorf(\"Tokenizer: %s isn't valid for predicate: %s of type: %s\",\n\t\t\t\t\ttokenizer.Name(), x.ParseAttr(schema.Predicate), typ.Name())\n\t\t\t}\n\t\t\tif _, ok := seen[tokenizer.Name()]; !ok {\n\t\t\t\tseen[tokenizer.Name()] = true\n\t\t\t} else {\n\t\t\t\treturn errors.Errorf(\"Duplicate tokenizers present for attr %s\",\n\t\t\t\t\tx.ParseAttr(schema.Predicate))\n\t\t\t}\n\t\t\tif tokenizer.IsSortable() {\n\t\t\t\tif seenSortableTok {\n\t\t\t\t\treturn errors.Errorf(\"More than one sortable index encountered for: %v\",\n\t\t\t\t\t\tschema.Predicate)\n\t\t\t\t}\n\t\t\t\tseenSortableTok = true\n\t\t\t}\n\t\t}\n\t}\n\treturn nil","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/schema/parse.go#L431-L467","documentation":"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.","triggerScenarios":"Mixing types and tokenizers: `count: int @index(term)`, `name: string @index(int)`, or `when: datetime @index(hash)` in a schema alteration.","commonSituations":"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).","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."],"exampleFix":"// before\ncount: int @index(term) .\n// after\ncount: int @index(int) .","handlingStrategy":"validation","validationCode":"const TOK_TYPE = {hash:'string',exact:'string',term:'string',fulltext:'string',trigram:'string',int:'int',float:'float',datetime:'datetime',geo:'geo',default:'bool'};\nfunction validateTypeMatch(predType, tokenizers) {\n  for (const t of tokenizers) {\n    if (TOK_TYPE[t] && TOK_TYPE[t] !== predType) {\n      throw new Error(`tokenizer ${t} invalid for type ${predType}`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await dgraph.Alter(ctx, op);\n} catch (e) {\n  if (String(e).includes(\"isn't valid for predicate\")) {\n    // fix tokenizer/type pairing and re-apply\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["dgraph","schema","tokenizer","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}