{"record":{"id":"c19df1ba35d6e06c","repo":"dgraph-io/dgraph","slug":"need-count-directive-in-schema-for-attr-s-for-f","errorCode":null,"errorMessage":"Need @count directive in schema for attr: %s for fn: %s at root","messagePattern":"Need @count directive in schema for attr: (.+?) for fn: (.+?) at root","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/task.go","lineNumber":1225,"sourceCode":"\t\treturn false\n\t}\n\n\t// If a predicate doesn't have @lang directive in schema, we don't need to do any string\n\t// filtering.\n\tif !schema.State().HasLang(attr) {\n\t\treturn false\n\t}\n\n\treturn langForFunc(langs) != \".\" &&\n\t\t(srcFn.fnType == standardFn || srcFn.fnType == hasFn ||\n\t\t\tsrcFn.fnType == fullTextSearchFn || srcFn.fnType == compareAttrFn ||\n\t\t\tsrcFn.fnType == customIndexFn || srcFn.fnType == ngramFn)\n}\n\nfunc (qs *queryState) handleCompareScalarFunction(ctx context.Context, arg funcArgs) error {\n\tattr := arg.q.Attr\n\tif ok := schema.State().HasCount(ctx, attr); !ok {\n\t\treturn errors.Errorf(\"Need @count directive in schema for attr: %s for fn: %s at root\",\n\t\t\tx.ParseAttr(attr), arg.srcFn.fname)\n\t}\n\tcounts := arg.srcFn.threshold\n\tcp := countParams{\n\t\tfn:      arg.srcFn.fname,\n\t\tcounts:  counts,\n\t\tattr:    attr,\n\t\tgid:     arg.gid,\n\t\treadTs:  arg.q.ReadTs,\n\t\treverse: arg.q.Reverse,\n\t}\n\treturn qs.evaluate(cp, arg.out)\n}\n\nfunc (qs *queryState) handleRegexFunction(ctx context.Context, arg funcArgs) error {\n\tspan := trace.SpanFromContext(ctx)\n\tstop := x.SpanTimer(span, \"handleRegexFunction\")\n\tdefer stop()","sourceCodeStart":1207,"sourceCodeEnd":1243,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/task.go#L1207-L1243","documentation":"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.","triggerScenarios":"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 .`.","commonSituations":"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.","solutions":["Add @count to the schema: `friend: [uid] @count .`","Wait for the count index to be built after altering the schema","Verify predicate name spelling in the query matches the schema","Restructure the query to avoid root-level count comparison if schema change is not possible"],"exampleFix":"// before\nfriend: [uid] .\n// after\nfriend: [uid] @count .","handlingStrategy":"validation","validationCode":"schema, _ := client.Query(ctx, `schema(pred: [friend]) {}`)\nif !strings.Contains(schema.String(), \"@count\") {\n    client.Alter(ctx, &api.Operation{Schema: \"friend: [uid] @count .\"})\n}","typeGuard":null,"tryCatchPattern":"resp, err := client.Query(ctx, q)\nif err != nil && strings.Contains(err.Error(), \"Need @count directive\") {\n    client.Alter(ctx, &api.Operation{Schema: \"friend: [uid] @count .\"})\n    time.Sleep(indexBuildWait)\n    resp, err = client.Query(ctx, q)\n}","preventionTips":["Add @count to any edge used in root-level count comparisons","Allow index build time after altering schema before running dependent queries","Verify predicate names match the schema exactly (typos break HasCount)"],"tags":["query","schema","count","index"],"backgroundTag":"missing-count-directive","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}