{"record":{"id":"a44a0016f7464b91","repo":"dgraph-io/dgraph","slug":"expected-groupbyres-to-have-length-0","errorCode":null,"errorMessage":"Expected GroupbyRes to have length > 0.","messagePattern":"Expected GroupbyRes to have length > 0\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/outputnode.go","lineNumber":1115,"sourceCode":"\tif sg.Params.IsEmpty {\n\t\treturn sg.addAggregations(enc, fj)\n\t}\n\n\tenc.curSize += uint64(len(sg.Params.Alias))\n\n\tattrID := enc.idForAttr(sg.Params.Alias)\n\tif sg.uidMatrix == nil {\n\t\tenc.AddListChild(fj, enc.newNode(attrID))\n\t\treturn nil\n\t}\n\n\thasChild, err := sg.handleCountUIDNodes(enc, fj, len(sg.DestUIDs.Uids))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif sg.Params.IsGroupBy {\n\t\tif len(sg.GroupbyRes) == 0 {\n\t\t\treturn errors.Errorf(\"Expected GroupbyRes to have length > 0.\")\n\t\t}\n\t\treturn sg.addGroupby(enc, fj, sg.GroupbyRes[0], sg.Params.Alias)\n\t}\n\n\tlenList := len(sg.uidMatrix[0].Uids)\n\tfor i := range lenList {\n\t\tuid := sg.uidMatrix[0].Uids[i]\n\t\tif algo.IndexOf(sg.DestUIDs, uid) < 0 {\n\t\t\t// This UID was filtered. So Ignore it.\n\t\t\tcontinue\n\t\t}\n\n\t\tn1 := enc.newNode(attrID)\n\t\tenc.setAttr(n1, enc.idForAttr(sg.Params.Alias))\n\t\tif err := sg.preTraverse(enc, uid, n1); err != nil {\n\t\t\tif err.Error() == \"_INV_\" {\n\t\t\t\tcontinue\n\t\t\t}","sourceCodeStart":1097,"sourceCodeEnd":1133,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/query/outputnode.go#L1097-L1133","documentation":"For @groupby queries, processNodeUids expects GroupbyRes to contain at least one result entry before calling addGroupby with GroupbyRes[0]. An empty GroupbyRes means the groupby aggregation produced nothing, which is treated as an internal consistency error rather than an empty response.","triggerScenarios":"A query with @groupby whose source UIDs match nothing (sg.DestUIDs empty or uidMatrix empty) yet Params.IsGroupBy is set, so sg.GroupbyRes is length 0 when encoding toFastJSON runs.","commonSituations":"@groupby on a predicate combined with a filter matching no nodes; groupby over an empty reverse edge; querying a groupby block before data exists (fresh instance / wrong namespace).","solutions":["Verify the groupby block actually matches data: run the inner func/filter without @groupby first","Add a has() filter or correct the predicate name so the block matches nodes","Guard client-side: catch this error and treat it as an empty result set if the data legitimately may not exist","Upgrade Dgraph if this occurs despite non-empty matches — it can indicate an encoding-path bug"],"exampleFix":"// before\n{\n  q(func: type(Person)) @groupby(neverIndexedPred) {\n    count(uid)\n  }\n}\n// after\n{\n  q(func: type(Person)) @filter(has(someField)) @groupby(city) {\n    count(uid)\n  }\n}","handlingStrategy":"try-catch","validationCode":"const [{ count }] = await dgraph.query('{ c(func: type(Person)) { count(uid) } }');\nif (count === 0) throw new Error('skip groupby: no source data');","typeGuard":null,"tryCatchPattern":"try {\n  return await dgraph.query(groupbyQuery);\n} catch (e) {\n  if (String(e).includes('Expected GroupbyRes to have length > 0')) {\n    return []; // treat as empty grouping\n  }\n  throw e;\n}","preventionTips":["Verify the groupby block matches data with a probe count query","Avoid @groupby on predicates that may be entirely absent","Filter the groupby source block with has() on the grouped predicate","Keep Dgraph patched; empty-groupby edge cases have been fixed over releases"],"tags":["dgraph","query","groupby","empty-result"],"backgroundTag":"groupby-empty-result","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}