dgraph-io/dgraph · error
Depth must be > 0 when loop is true for recurse query
Error message
Depth must be > 0 when loop is true for recurse query
What it means
When a recurse query sets allowLoops: true but does not specify a depth (or depth is 0), Dgraph rejects the query: without a depth bound, loop-allowed recursion could traverse forever. Depth must be explicitly positive when loops are permitted.
Source
Thrown at query/recurse.go:200
newChild := new(SubGraph)
newChild.copyFiltersRecurse(child)
newChild.SrcUIDs = sg.DestUIDs
newChild.Params.Var = child.Params.Var
sg.Children = append(sg.Children, newChild)
out = append(out, newChild)
}
return out, nil
}
func recurse(ctx context.Context, sg *SubGraph) error {
if !sg.Params.Recurse {
return errors.Errorf("Invalid recurse path query")
}
depth := sg.Params.RecurseArgs.Depth
if depth == 0 {
if sg.Params.RecurseArgs.AllowLoop {
return errors.Errorf("Depth must be > 0 when loop is true for recurse query")
}
// If no depth is specified, expand till we reach all leaf nodes
// or we see reach too many nodes.
depth = math.MaxUint64
}
for _, child := range sg.Children {
if len(child.Children) > 0 {
return errors.Errorf(
"recurse queries require that all predicates are specified in one level")
}
}
return sg.expandRecurse(ctx, depth)
}
View on GitHub (pinned to 759e242be6)
Solutions
- Add an explicit positive depth: @recurse(depth: 3, allowLoops: true)
- If you didn't intend loops, remove allowLoops and rely on the default depth-until-leaves behavior
- Estimate max cycle length in your data and set depth just above it to control cost
Example fix
// before
{
me(func: eq(name, "a")) @recurse(allowLoops: true) {
friend
}
}
// after
{
me(func: eq(name, "a")) @recurse(depth: 3, allowLoops: true) {
friend
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate depth>0 whenever allowLoops is set
if strings.Contains(dql, "allowLoops: true") {
m := regexp.MustCompile(`@recurse\(depth:\s*(\d+)`).FindStringSubmatch(dql)
if len(m) < 2 || m[1] == "0" {
return errors.New("allowLoops requires depth > 0")
}
} Try / catch
resp, err := txn.Query(ctx, dql)
if err != nil && strings.Contains(err.Error(), "Depth must be > 0") {
return fmt.Errorf("fix DQL: add depth argument to @recurse: %w", err)
} Prevention
- Always pair allowLoops: true with an explicit depth
- Default depth-until-leaves only works when loops are disallowed
- Test cycle-heavy datasets with small depth first
When it happens
Trigger: Running @recurse(allowLoops: true) with no depth argument, or with depth: 0, e.g. @recurse(allowLoops: true) or @recurse(depth: 0, allowLoops: true).
Common situations: Graph data containing cycles where developers enable allowLoops to revisit nodes but forget the depth bound; copying examples of allowLoops without depth.
Related errors
- recurse queries require that all predicates are specified in
- Invalid recurse path query
- NQuad failed sanity check. Subject: %q, Predicate: %q, Objec
- empty variable name in function call
- empty facetKeys not allowed
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/f7a9300e6c17ad47.
Report an issue: GitHub.