dgraph-io/dgraph · error
Vars can be assigned only when grouped by UID attribute
Error message
Vars can be assigned only when grouped by UID attribute
What it means
When filling a groupby-exported variable, fillGroupedVars type-asserts the single group key value to uint64 (a UID). If the grouped attribute is not a UID (e.g. a string or int predicate), the variable cannot be keyed by UID, so the query is rejected.
Source
Thrown at query/groupby.go:348
}
}
if child.Params.Var == "" {
continue
}
chVar := child.Params.Var
tempMap := types.NewShardedMap()
for _, grp := range res.group {
if len(grp.keys) == 0 {
continue
}
if len(grp.keys) > 1 {
return errors.Errorf("Expected one UID for var in groupby but got: %d", len(grp.keys))
}
uidVal := grp.keys[0].key.Value
uid, ok := uidVal.(uint64)
if !ok {
return errors.Errorf("Vars can be assigned only when grouped by UID attribute")
}
// grp.aggregates could be empty if schema conversion failed during aggregation
if len(grp.aggregates) > 0 {
tempMap.Set(uid, grp.aggregates[len(grp.aggregates)-1].key)
}
}
doneVars[chVar] = varValue{
Vals: tempMap,
path: append(path, pathNode),
}
}
return nil
}
func (sg *SubGraph) processGroupBy(doneVars map[string]varValue, path []*SubGraph) error {
for _, ul := range sg.uidMatrix {
// We need to process groupby for each list as grouping needs to happen for each path of the
// tree.View on GitHub (pinned to 759e242be6)
Solutions
- Change the groupby attribute to uid (or another UID-valued predicate) so the exported variable can be keyed by UID
- Remove the AS export and use plain aggregation inside groupby without reusing the variable elsewhere
- Compute the aggregate with a separate @groupby/sum query structure that does not bind variables
Example fix
// before
{
users(func: type(User)) {
groupby(name) {
total as count(posts)
}
}
}
// after
{
users(func: type(User)) {
groupby(uid) {
total as count(posts)
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure the groupby attribute is UID-valued when exporting a variable:
function validateGroupbyAttrIsUid(attr, exportsVar) {
if (exportsVar && attr !== 'uid') {
throw new Error('Vars can only be exported when grouped by uid');
}
} Try / catch
try {
const res = await dgraph.newTxn().query(query);
} catch (e) {
if (String(e).includes('grouped by UID attribute')) {
// rewrite query to groupby(uid) or drop the AS export
} else throw e;
} Prevention
- Only export groupby variables when grouping on uid
- Do not swap the groupby attribute of a template that exports variables without checking UID-ness
- Prefer computing aggregates client-side when grouping on non-UID attributes
When it happens
Trigger: `AS` variable export inside groupby where the grouped key is a non-UID attribute (e.g. groupby(name) with total as sum(x)), so grp.keys[0].key.Value is not uint64.
Common situations: Grouping on a string predicate while exporting an aggregate variable; assuming variables work with any groupby attribute; copying a uid-grouped template and swapping the attribute.
Related errors
- Expected one UID for var in groupby but got: %d
- groupby is not supported in rdf output format
- Only uid predicate is allowed in count within groupby
- Expected GroupbyRes to have length > 0.
- Unexpected length while adding Groupby. Idx: [%v], len: [%v]
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/b7044fb2424fa92c.
Report an issue: GitHub.