dgraph-io/dgraph · error
from variable(%s) should only expand to 1 uid
Error message
from variable(%s) should only expand to 1 uid
What it means
Shortest-path queries require exactly one start node. When the 'from' endpoint comes from a variable, Dgraph checks that the variable resolves to at most one UID; if it expands to multiple UIDs the path is ambiguous and this error is thrown.
Source
Thrown at query/query.go:1781
}
// fillShortestPathVars reads value of the uid variable from mp map and fills it into From and To
// parameters.
func (sg *SubGraph) fillShortestPathVars(mp map[string]varValue) error {
// The uidVar.Uids can be nil or have an empty uid list if the variable didn't
// return any uids. This would mean sg.Params.From or sg.Params.To is 0 and the
// query would return an empty result.
if sg.Params.ShortestPathArgs.From != nil && len(sg.Params.ShortestPathArgs.From.NeedsVar) > 0 {
fromVar := sg.Params.ShortestPathArgs.From.NeedsVar[0].Name
uidVar, ok := mp[fromVar]
if !ok {
return errors.Errorf("value of from var(%s) should have already been populated",
fromVar)
}
if uidVar.Uids != nil && len(uidVar.Uids.Uids) > 0 {
if len(uidVar.Uids.Uids) > 1 {
return errors.Errorf("from variable(%s) should only expand to 1 uid", fromVar)
}
sg.Params.From = uidVar.Uids.Uids[0]
}
}
if sg.Params.ShortestPathArgs.To != nil && len(sg.Params.ShortestPathArgs.To.NeedsVar) > 0 {
toVar := sg.Params.ShortestPathArgs.To.NeedsVar[0].Name
uidVar, ok := mp[toVar]
if !ok {
return errors.Errorf("value of to var(%s) should have already been populated",
toVar)
}
if uidVar.Uids != nil && len(uidVar.Uids.Uids) > 0 {
if len(uidVar.Uids.Uids) > 1 {
return errors.Errorf("to variable(%s) should only expand to 1 uid", toVar)
}
sg.Params.To = uidVar.Uids.Uids[0]
}View on GitHub (pinned to 759e242be6)
Solutions
- Narrow the variable's query so it matches exactly one node (add a unique filter like eq(email, ...) or first: 1)
- Use a literal UID in shortest(from:) if the node is known
- Use a more specific predicate to disambiguate
- Inspect the variable's contents by running the emitting clause alone
Example fix
// before: matches many
f as var(func: eq(type, "Person"))
p(func: uid(0x1)) { shortest(from: var(f), to: 0x2) { uid } }
// after: exactly one
f as var(func: eq(email, "alice@example.com"))
p(func: uid(0x1)) { shortest(from: var(f), to: 0x2) { uid } } Defensive patterns
Strategy: validation
Validate before calling
// Run the emitting clause first and assert it yields exactly one node
if countNodes(emittingClause) != 1 {
return fmt.Errorf("from-variable must resolve to exactly one node")
} Try / catch
if err != nil && strings.Contains(err.Error(), "should only expand to 1 uid") && strings.Contains(err.Error(), "from") {
return fmt.Errorf("from-variable ambiguous; narrow the filter: %w", err)
} Prevention
- Filter variable clauses on a unique predicate (email, external id)
- Add first: 1 when a single node must be selected
- Assert variable cardinality in integration tests
When it happens
Trigger: shortest(from: var(f), ...) where var(f) matched multiple nodes, e.g. 'f as var(func: eq(type, "Person"))' matching many people, or a uid variable accumulated multiple UIDs.
Common situations: Filter too broad in the variable-emitting clause; using a variable populated from a multi-result query; expecting Dgraph to pick a node automatically.
Related errors
- value of from var(%s) should have already been populated
- value of to var(%s) should have already been populated
- to variable(%s) should only expand to 1 uid
- from/to can't be nil for shortest path
- Invalid variable aggregation. Check the levels.
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/962c8f2c42f414e0.
Report an issue: GitHub.