dgraph-io/dgraph · error
facets format should be of type map for scalarlist predicate
Error message
facets format should be of type map for scalarlist predicates, found: %v for facet: %v
What it means
The hash tokenizer computes a BLAKE2b-256 digest of a string value. Because hashing is only defined for string inputs here, Tokens() type-asserts v.(string) and returns this error for any other dynamic type.
Source
Thrown at chunker/json_parser.go:133
// Map key would be the index of scalar value for respective facets.
func parseMapFacets(m map[string]interface{}, prefix string) ([]map[int]*api.Facet, error) {
// This happens at root.
if prefix == "" {
return nil, nil
}
var mapSlice []map[int]*api.Facet
for fname, facetVal := range m {
if facetVal == nil {
continue
}
if !strings.HasPrefix(fname, prefix) {
continue
}
fm, ok := facetVal.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("facets format should be of type map for "+
"scalarlist predicates, found: %v for facet: %v", facetVal, fname)
}
idxMap := make(map[int]*api.Facet, len(fm))
for sidx, val := range fm {
key := fname[len(prefix):]
facet, err := handleBasicFacetsType(key, val)
if err != nil {
return nil, fmt.Errorf("facet: %s, index: %s: %w", fname, sidx, err)
}
idx, err := strconv.Atoi(sidx)
if err != nil {
return nil, fmt.Errorf("facet: %s, index: %s: %w", fname, sidx, err)
}
idxMap[idx] = facet
}
mapSlice = append(mapSlice, idxMap)
}View on GitHub (pinned to 759e242be6)
Solutions
- Make the predicate a string type in the schema if hash indexing is desired.
- Convert the value with fmt.Sprintf or strconv before calling Tokens.
- Remove @index(hash) from non-string predicates.
Example fix
// before
tok.HashTokenizer{}.Tokens(12345) // error
// after
tok.HashTokenizer{}.Tokens(strconv.FormatInt(12345, 10)) Defensive patterns
Strategy: type-guard
Validate before calling
if s, ok := v.(string); !ok {
return fmt.Errorf("hash tokenizer requires string, got %T", v)
} Type guard
func isHashableString(v interface{}) bool { _, ok := v.(string); return ok } Try / catch
tokens, err := hashTok.Tokens(v)
if err != nil && strings.Contains(err.Error(), "Hash tokenizer only supported for string") {
s := fmt.Sprintf("%v", v)
tokens, err = hashTok.Tokens(s)
} Prevention
- Only use @index(hash) on string predicates.
- Stringify values (strconv/fmt) before tokenizing non-string scalars.
- Centralize tokenization behind a helper that enforces the string type.
When it happens
Trigger: Calling HashTokenizer.Tokens(v) with a non-string value — e.g. tokenizing an int64 uid value or bool through the hash index path.
Common situations: Schema uses @index(hash) on a non-string predicate; code passes []byte or typed values without converting to string before tokenization.
Related errors
- UID must be present and non-zero while deleting edges
- facet value can only be string/number/bool
- facet: %s, index: %s: %w
- Tokenizer: %s isn't valid for predicate: %s of type: %s
- illegal rune found "%c", expecting {
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/6af28d8988b2346c.
Report an issue: GitHub.