{"record":{"id":"33e97db0e7b712c2","repo":"dgraph-io/dgraph","slug":"node-with-count-cannot-have-child-attributes","errorCode":null,"errorMessage":"Node with count cannot have child attributes","messagePattern":"Node with count cannot have child attributes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/query.go","lineNumber":589,"sourceCode":"\n\t\t// Inherit from the parent.\n\t\tif len(sg.Params.Cascade.Fields) > 0 {\n\t\t\targs.Cascade.Fields = append(args.Cascade.Fields, sg.Params.Cascade.Fields...)\n\t\t}\n\t\t// Allow over-riding at this level.\n\t\tif len(gchild.Cascade) > 0 {\n\t\t\targs.Cascade.Fields = gchild.Cascade\n\t\t}\n\n\t\t// Remove pagination arguments from the query if @cascade is mentioned since\n\t\t// pagination will be applied post processing the data.\n\t\tif len(args.Cascade.Fields) > 0 {\n\t\t\targs.addCascadePaginationArguments(gchild)\n\t\t}\n\n\t\tif gchild.IsCount {\n\t\t\tif len(gchild.Children) != 0 {\n\t\t\t\treturn errors.New(\"Node with count cannot have child attributes\")\n\t\t\t}\n\t\t\targs.DoCount = true\n\t\t}\n\n\t\tfor argk := range gchild.Args {\n\t\t\tif !isValidArg(argk) {\n\t\t\t\treturn errors.Errorf(\"Invalid argument: %s\", argk)\n\t\t\t}\n\t\t}\n\t\tif err := args.fill(gchild); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif len(args.Order) != 0 && len(args.FacetsOrder) != 0 {\n\t\t\treturn errors.Errorf(\"Cannot specify order at both args and facets\")\n\t\t}\n\n\t\tdst := &SubGraph{","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/query/query.go#L571-L607","documentation":"A count(...) aggregation node reduces a level to a single number and therefore cannot itself contain child attributes. treeCopy checks gchild.IsCount and rejects any node with children, since there is no place to attach their results. The count must be a leaf of the query tree.","triggerScenarios":"Writing `count(friend) { name }` or `friend { count(uid) { name } }` — any count node followed by a brace block with children.","commonSituations":"Users trying to count and fetch attributes in one traversal; migrating SQL-style SELECT COUNT(col), other_col mental models into Dgraph; query builders that attach children to every node.","solutions":["Remove the child attributes and make the count a leaf: `count(friend)`","Fetch the attributes in a sibling level: one branch counts, a sibling branch lists children","Use two queries or aliases if both the count and the sample of children are required"],"exampleFix":"// before\n{\n  me(func: uid(0x1)) {\n    count(friend) {\n      name\n    }\n  }\n}\n// after\n{\n  me(func: uid(0x1)) {\n    total as count(friend)\n    friend {\n      name\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"function assertCountIsLeaf(node) {\n  if (/^count\\s*\\(/.test(node.field) && Array.isArray(node.children) && node.children.length > 0) {\n    throw new Error('count(...) node must not have child attributes');\n  }\n}","typeGuard":"const isCountWithChildren = (n) => n.isCount === true && n.children && n.children.length > 0;","tryCatchPattern":"try {\n  await txn.query(q);\n} catch (e) {\n  if (e.message === 'Node with count cannot have child attributes') {\n    throw new Error('Move child attributes to a sibling level of the count');\n  }\n  throw e;\n}","preventionTips":["Treat count(...) nodes as leaves always","Fetch attributes in a sibling branch with an alias","Query builders: skip child emission when the field is wrapped in count()"],"tags":["dgraph","query","count","validation"],"backgroundTag":"invalid-query-argument","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}