dgraph-io/dgraph · error

Need @count directive in schema for attr: %s for fn: %s at r

Error message

Need @count directive in schema for attr: %s for fn: %s at root

What it means

handleCompareScalarFunction supports comparison functions (ge, gt, le, lt, etc.) at root that rely on the count index. The predicate must have the @count directive in the schema, otherwise this error is thrown.

Source

Thrown at worker/task.go:1225

		return false
	}

	// If a predicate doesn't have @lang directive in schema, we don't need to do any string
	// filtering.
	if !schema.State().HasLang(attr) {
		return false
	}

	return langForFunc(langs) != "." &&
		(srcFn.fnType == standardFn || srcFn.fnType == hasFn ||
			srcFn.fnType == fullTextSearchFn || srcFn.fnType == compareAttrFn ||
			srcFn.fnType == customIndexFn || srcFn.fnType == ngramFn)
}

func (qs *queryState) handleCompareScalarFunction(ctx context.Context, arg funcArgs) error {
	attr := arg.q.Attr
	if ok := schema.State().HasCount(ctx, attr); !ok {
		return errors.Errorf("Need @count directive in schema for attr: %s for fn: %s at root",
			x.ParseAttr(attr), arg.srcFn.fname)
	}
	counts := arg.srcFn.threshold
	cp := countParams{
		fn:      arg.srcFn.fname,
		counts:  counts,
		attr:    attr,
		gid:     arg.gid,
		readTs:  arg.q.ReadTs,
		reverse: arg.q.Reverse,
	}
	return qs.evaluate(cp, arg.out)
}

func (qs *queryState) handleRegexFunction(ctx context.Context, arg funcArgs) error {
	span := trace.SpanFromContext(ctx)
	stop := x.SpanTimer(span, "handleRegexFunction")
	defer stop()

View on GitHub (pinned to 759e242be6)

Solutions

  1. Add @count to the schema: `friend: [uid] @count .`
  2. Wait for the count index to be built after altering the schema
  3. Verify predicate name spelling in the query matches the schema
  4. Restructure the query to avoid root-level count comparison if schema change is not possible

Example fix

// before
friend: [uid] .
// after
friend: [uid] @count .
Defensive patterns

Strategy: validation

Validate before calling

schema, _ := client.Query(ctx, `schema(pred: [friend]) {}`)
if !strings.Contains(schema.String(), "@count") {
    client.Alter(ctx, &api.Operation{Schema: "friend: [uid] @count ."})
}

Try / catch

resp, err := client.Query(ctx, q)
if err != nil && strings.Contains(err.Error(), "Need @count directive") {
    client.Alter(ctx, &api.Operation{Schema: "friend: [uid] @count ."})
    time.Sleep(indexBuildWait)
    resp, err = client.Query(ctx, q)
}

Prevention

When it happens

Trigger: Root query using count-based comparison like `count(friend) > 3` (has(friend) with count funcs, e.g. `query { q(func: gt(count(friend), 3)) }`) where schema lacks `friend: [uid] @count .`.

Common situations: Running count-comparison queries before adding @count to the schema; @count added but index still building; typo in predicate name so HasCount looks up the wrong predicate.

Related errors


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