{"record":{"id":"8ea8e79424cd3882","repo":"dgraph-io/dgraph","slug":"more-than-one-sortable-index-encountered-for-v","errorCode":null,"errorMessage":"More than one sortable index encountered for: %v","messagePattern":"More than one sortable index encountered for: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/parse.go","lineNumber":460,"sourceCode":"\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\n}\n\nfunc parseTypeDeclaration(it *lex.ItemIterator, ns uint64) (*pb.TypeUpdate, error) {\n\t// Iterator is currently on the token corresponding to the keyword type.\n\tif it.Item().Typ != itemText || it.Item().Val != \"type\" {\n\t\treturn nil, it.Item().Errorf(\"Expected type keyword. Got %v\", it.Item().Val)\n\t}\n\n\tit.Next()\n\tif it.Item().Typ != itemText {\n\t\treturn nil, it.Item().Errorf(\"Expected type name. Got %v\", it.Item().Val)","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/schema/parse.go#L442-L478","documentation":"Dgraph allows at most one sortable tokenizer (exact for strings, the default tokenizer for int/float/datetime) per predicate, because sorting requires a single ordering; a second sortable tokenizer would create conflicting sort orders. resolveTokenizers fails the update when a second tokenizer with IsSortable() is encountered.","triggerScenarios":"`pred: string @index(exact, exact) .` (also a duplicate) or any directive containing two sortable tokenizers, e.g. hypothetically `@index(exact, hash)` plus another sortable entry added by tooling.","commonSituations":"Tooling that appends an 'exact' tokenizer for sorting to a schema that already lists one; misunderstanding that multiple string tokenizers are fine but multiple sortable ones are not; generated schemas merging sort and filter requirements.","solutions":["Keep exactly one sortable tokenizer (typically `exact` for sortable strings).","Use non-sortable tokenizers (hash, term, fulltext, trigram) for matching, and `exact` only once if you need order: `@index(hash, exact) .`","If both sorting and duplicate-free matching are needed, this combination is supported — just don't repeat sortable entries.","Re-apply the alteration."],"exampleFix":"// before\nname: string @index(exact, exact) .\n// after\nname: string @index(hash, exact) .","handlingStrategy":"validation","validationCode":"const SORTABLE = new Set(['exact', 'int', 'float', 'datetime', 'default']);\nfunction validateSingleSortable(tokenizers) {\n  const sortables = tokenizers.filter(t => SORTABLE.has(t));\n  if (sortables.length > 1) throw new Error('more than one sortable tokenizer: ' + sortables);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await dgraph.Alter(ctx, op);\n} catch (e) {\n  if (String(e).includes('More than one sortable index')) {\n    // keep a single sortable tokenizer and retry\n  }\n  throw e;\n}","preventionTips":["List at most one sortable tokenizer (exact for strings) per predicate","Use hash/term/fulltext/trigram for matching and exact only when sorting/order is needed","Review tooling that appends 'exact' automatically for sorting support"],"tags":["dgraph","schema","tokenizer","sortable"],"backgroundTag":"schema-validation-failed","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}