dgraph-io/dgraph · error
Only aggregated variables allowed within empty block.
Error message
Only aggregated variables allowed within empty block.
What it means
When a sub-block of a query yields no UIDs, Dgraph still tries to surface its aggregated variables. If the aggregation block is empty AND it has no tracked input variables (NeedsVar empty), there is no aggregation value to encode — the query only contained non-aggregation content in an empty block, which is invalid.
Source
Thrown at query/outputnode.go:1045
}
}
for _, it := range grp.aggregates {
if err := enc.AddValue(uc, enc.idForAttr(it.attr), it.key); err != nil {
return err
}
}
enc.AddListChild(g, uc)
}
enc.AddListChild(fj, g)
return nil
}
func (sg *SubGraph) addAggregations(enc *encoder, fj fastJsonNode) error {
for _, child := range sg.Children {
aggVal, ok := child.Params.UidToVal.Get(0)
if !ok {
if len(child.Params.NeedsVar) == 0 {
return errors.Errorf("Only aggregated variables allowed within empty block.")
}
// the aggregation didn't happen, most likely was called with unset vars.
// See: query.go:fillVars
// In this case we do nothing. The aggregate value in response will be returned as NULL.
}
if child.Params.Normalize && child.Params.Alias == "" {
continue
}
fieldName := child.aggWithVarFieldName()
n1 := enc.newNode(enc.idForAttr(sg.Params.Alias))
if err := enc.AddValue(n1, enc.idForAttr(fieldName), aggVal); err != nil {
return err
}
enc.AddListChild(fj, n1)
}
if enc.IsEmpty(fj) {
enc.AddListChild(fj, enc.newNode(enc.idForAttr(sg.Params.Alias)))
}View on GitHub (pinned to 759e242be6)
Solutions
- Fix the variable name/declaration so the aggregation references a var actually produced by an earlier block
- Loosen or correct the filter that empties the block so it matches nodes
- Ensure aggregate(math(...)) blocks reference grouped/source variables (aggregations require an input var)
- Check query.go fillVars path: confirm the upstream block that should set the var actually executes before this block
Example fix
// before
{
var(func: has(score)) @filter(gt(score, 100)) {
s as score
}
q(func: uid(0)) {
total as sum(val(s))
}
}
// after: guard for empty result or fix filter
{
var(func: has(score)) {
s as score
}
q(func: uid(0)) {
total as sum(val(s))
}
} Defensive patterns
Strategy: validation
Validate before calling
// verify the source block matches before running the aggregation query
const probe = await dgraph.query('{ p(func: has(score)) @filter(gt(score, 100)) { uid } }');
if (!probe.p.length) throw new Error('aggregation source block is empty; fix filter/vars first'); Try / catch
try {
return await dgraph.query(q);
} catch (e) {
if (String(e).includes('Only aggregated variables allowed within empty block')) {
// treat as empty aggregate: return 0/null, or retry with corrected variable names
}
throw e;
} Prevention
- Ensure every aggregate(math(...)) references a var bound by an earlier block
- Double-check variable names for typos (var 's' vs 'as s')
- Probe filters with a count query before aggregations
- Keep aggregation variables and their sources in the same query path
When it happens
Trigger: A query block that matches zero nodes containing a math/aggregate variable whose source variables were never set or matched nothing, so UidToVal.Get(0) fails and child.Params.NeedsVar is empty during addAggregations (called from processNodeUids).
Common situations: Aggregate inside a block filtered to zero results where the var was declared with the wrong name or the filter excludes everything; typos in variable names so fillVars never populates them; @groupby/math blocks under empty parent UIDs.
Related errors
- Expected GroupbyRes to have length > 0.
- Node with %q cant have child attr
- Node with %q cant have filter, please place the filter on th
- Invalid variable aggregation. Check the levels.
- Error in applying aggregation %s
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/d5f350b0c148753b.
Report an issue: GitHub.