dgraph-io/dgraph · error

Attribute %s is not indexed.

Error message

Attribute %s is not indexed.

What it means

After confirming the attribute is scalar, indexTokens checks schema.State().IsIndexed; if the predicate has no @index directive in the schema, indexing is refused with 'Attribute %s is not indexed.' This ensures tokens are only built for predicates the schema declares indexable, keeping the index consistent with schema configuration.

Source

Thrown at posting/index.go:62

	factorySpecs []*tok.FactoryCreateSpec
	edge         *pb.DirectedEdge // Represents the original uid -> value edge.
	val          types.Val
	op           pb.DirectedEdge_Op
}

// indexTokens return tokens, without the predicate prefix and
// index rune, for specific tokenizers.
func indexTokens(ctx context.Context, info *indexMutationInfo) ([]string, error) {
	attr := info.edge.Attr
	lang := info.edge.GetLang()

	schemaType, err := schema.State().TypeOf(attr)
	if err != nil || !schemaType.IsScalar() {
		return nil, errors.Errorf("Cannot index attribute %s of type object.", attr)
	}

	if !schema.State().IsIndexed(ctx, attr) {
		return nil, errors.Errorf("Attribute %s is not indexed.", attr)
	}
	sv, err := types.Convert(info.val, schemaType)
	if err != nil {
		return nil, err
	}

	var tokens []string
	for _, it := range info.tokenizers {
		toks, err := tok.BuildTokens(sv.Value, tok.GetTokenizerForLang(it, lang))
		if err != nil {
			return tokens, err
		}
		tokens = append(tokens, toks...)
	}
	return tokens, nil
}

// addIndexMutations adds mutation(s) for a single term, to maintain the index,

View on GitHub (pinned to 759e242be6)

Solutions

  1. Update the schema to add @index to the predicate (e.g. 'name: string @index(hash) .' via /alter) before writing data
  2. Verify schema with 'schema(pred: name){}' or curl the /state endpoint that the index is present in the target cluster
  3. Align deployment pipelines so schema alterations run before data loads
  4. If the predicate genuinely should not be indexed, route the mutation through the non-indexing path

Example fix

// before: schema has 'name: string .'
// after: alter schema first
curl -X POST localhost:8080/alter -d 'name: string @index(hash) .'
// then retry the mutation
Defensive patterns

Strategy: validation

Validate before calling

// Verify @index is present before writing
sch, err := client.Schema(ctx, "name")
if err != nil || len(sch.Index) == 0 {
    return fmt.Errorf("predicate %q has no @index in schema; run alter first", "name")
}

Type guard

func isIndexed(sch *api.Schema) bool { return sch != nil && len(sch.Index) > 0 }

Try / catch

err := mutateWithIndex(ctx, edge)
if err != nil && strings.Contains(err.Error(), "is not indexed") {
    return fmt.Errorf("add @index to predicate %q via /alter before writing", edge.Attr)
}

Prevention

When it happens

Trigger: A mutation (AddMutationWithIndex → addIndexMutations → indexTokens) targets a scalar predicate that exists in the schema but lacks an index (no @index term), e.g. writing to 'name: string .' which has no hash/exact/term index.

Common situations: Inserting data before applying the @index schema update; schema altered to drop an index while old writers still push mutations; environment drift where the test cluster has indexes but production does not.

Related errors


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