dgraph-io/dgraph · error
recurse queries require that all predicates are specified in
Error message
recurse queries require that all predicates are specified in one level
What it means
Recurse queries only support one level of predicates: every child of the recurse root must be a leaf. If any child block itself has nested children, Dgraph rejects the query because nested expansion under recursion is not supported.
Source
Thrown at query/recurse.go:209
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
- Flatten the query: list all desired predicates as direct children of the recurse block
- Move any nested selection fields up one level, dropping deeper nesting
- If nested traversal shape is required, use multiple queries or shortest-path/normal queries instead of recurse
Example fix
// before: nested children under recurse
{
me(func: eq(name, "a")) @recurse {
friend {
name
know {
age
}
}
}
}
// after: one level only
{
me(func: eq(name, "a")) @recurse {
friend
name
}
} Defensive patterns
Strategy: validation
Validate before calling
// Reject nested blocks under recurse before sending
inRecurse := false
bracketDepth := 0
for _, line := range strings.Split(dql, "\n") {
if strings.Contains(line, "@recurse") { inRecurse = true; continue }
bracketDepth += strings.Count(line, "{") - strings.Count(line, "}")
if inRecurse && bracketDepth > 1 {
return errors.New("recurse supports only one level of predicates")
}
} Try / catch
resp, err := txn.Query(ctx, dql)
if err != nil && strings.Contains(err.Error(), "one level") {
return fmt.Errorf("flatten recurse query: %w", err) // fix DQL, don't retry
} Prevention
- Keep recurse children as flat predicate lists
- Move nested selections into separate queries
- Lint generated DQL for nesting depth under @recurse blocks
When it happens
Trigger: Writing a @recurse query where a child edge block contains its own nested block, e.g. @recurse { friend { name { x } } }, or adding @filter/directives blocks that create child SubGraphs with children.
Common situations: Copy-pasting a nested normal query and adding @recurse on top; assuming recursion supports arbitrary nesting like regular queries do.
Related errors
- Depth must be > 0 when loop is true for recurse query
- 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/3c0af3c1c17d799a.
Report an issue: GitHub.