dgraph-io/dgraph · error

Couldn't evaluate @normalize directive - too many results

Error message

Couldn't evaluate @normalize directive - too many results

What it means

The @normalize directive flattens and merges result branches into edge-list form. During merge, Dgraph caps total materialized nodes with the LimitNormalizeNode config; exceeding it aborts the query since the response would be unbounded.

Source

Thrown at query/outputnode.go:901

	return nn
}

func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) {
	if len(parent) == 0 {
		return child, nil
	}

	// Here we merge two slices of maps.
	mergedList := make([]fastJsonNode, 0)
	cnt := 0
	for _, pa := range parent {
		for _, ca := range child {
			paCopy, paNodeCount := enc.copyFastJsonList(pa)
			caCopy, caNodeCount := enc.copyFastJsonList(ca)

			cnt += paNodeCount + caNodeCount
			if cnt > x.Config.LimitNormalizeNode {
				return nil, errors.Errorf(
					"Couldn't evaluate @normalize directive - too many results")
			}

			if paCopy == nil {
				paCopy = caCopy
			} else {
				temp := paCopy
				for temp.next != nil {
					temp = temp.next
				}
				temp.next = caCopy
			}
			mergedList = append(mergedList, paCopy)
		}
	}
	return mergedList, nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Add tighter filters/pagination (first, offset) to the root or nested blocks to reduce result count
  2. Raise the limit via --limit and/or the LIMIT_NORMALIZE_NODE option (same name) in Greater Limit options if the result size is genuinely intended
  3. Restructure the query: split into smaller queries without @normalize, or aggregate instead of returning every edge
  4. Filter child edges (e.g. @filter(has(...))) so fewer branches are merged per parent

Example fix

// before
{
  q(func: type(Person)) @normalize {
    name
    friend { friendName: name }
  }
}
// after
{
  q(func: type(Person), first: 1000) @normalize {
    name
    friend (first: 10) { friendName: name }
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// estimate result size first with a count query
const [{ count }] = await dgraph.query('{ c(func: type(Person)) { count(uid) } }');
if (count * avgFanout > 1_000_000) throw new Error('normalize result would exceed limit; paginate');

Try / catch

try {
  return await dgraph.query(q); // q uses @normalize
} catch (e) {
  if (String(e).includes('too many results') && /normalize/.test(q)) {
    return await dgraph.query(paginate(q)); // retry with first/offset
  }
  throw e;
}

Prevention

When it happens

Trigger: A @normalize query whose combined parent+child lists exceed x.Config.LimitNormalizeNode (default 1e6) — e.g. a broad root match with a nested reverse edge expanded for every node, cross-producting results.

Common situations: Queries on large graphs without filters; @normalize combined with recurse or expand(_all_); instances with default LIMIT_NORMALIZE_NODE config on datasets larger than intended.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/be19f15b18c1661d. Report an issue: GitHub.