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

  1. Flatten the query: list all desired predicates as direct children of the recurse block
  2. Move any nested selection fields up one level, dropping deeper nesting
  3. 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

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


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