dgraph-io/dgraph · error

facet value can only be string/number/bool

Error message

facet value can only be string/number/bool

What it means

The trigram tokenizer splits a string into all 3-character substrings for trigram indexing. Tokens() asserts the input is a string; any other dynamic type returns this error since trigram indexing is defined only for strings.

Source

Thrown at chunker/json_parser.go:90

			if err != nil {
				return nil, err
			}
			jsonValue = jsonInt
			valueType = api.Facet_INT
		}
	// these int64/float64 cases are needed for the FastParseJSON simdjson
	// parser, which doesn't use json.Number
	case int64:
		jsonValue = v
		valueType = api.Facet_INT
	case float64:
		jsonValue = v
		valueType = api.Facet_FLOAT
	case bool:
		jsonValue = v
		valueType = api.Facet_BOOL
	default:
		return nil, errors.New("facet value can only be string/number/bool")
	}

	// Convert facet val interface{} to binary.
	binaryValueFacet, err := facets.ToBinary(key, jsonValue, valueType)
	if err != nil {
		return nil, err
	}

	return binaryValueFacet, nil
}

// parseMapFacets parses facets which are of map type. Facets for scalar list predicates are
// specified in map format. For example below predicate nickname and kind facet associated with it.
// Here nickname "bob" doesn't have any facet associated with it.
//
//	{
//		"nickname": ["alice", "bob", "josh"],
//		"nickname|kind": {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Ensure the predicate indexed with trigram is of type string in the schema.
  2. Remove @index(trigram) from non-string predicates or switch to a suitable index.
  3. Cast/convert the value to string at the call site when intentional.

Example fix

// before
pred: "released" @index(trigram) . // datetime
// after
pred: "title" @index(trigram) . // string
Defensive patterns

Strategy: type-guard

Validate before calling

if s, ok := v.(string); !ok {
    return fmt.Errorf("trigram tokenizer requires string, got %T", v)
}

Type guard

func asString(v interface{}) (string, bool) { s, ok := v.(string); return s, ok }

Try / catch

tokens, err := trigramTok.Tokens(v)
if err != nil && strings.Contains(err.Error(), "Trigram indices only supported for string") {
    return nil, fmt.Errorf("trigram index requires a string predicate; got %T", v)
}

Prevention

When it happens

Trigger: Calling TrigramTokenizer.Tokens(v) with a non-string value (int, float, bool, time.Time, []byte, etc.).

Common situations: Schema has @index(trigram) on a non-string predicate (e.g. a datetime or int); generic indexing code passes interface{} values straight to the tokenizer without a string check.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/7cc44272fc1e3843. Report an issue: GitHub.