{"record":{"id":"75c73671776ad78a","repo":"dgraph-io/dgraph","slug":"to-variable-s-should-only-expand-to-1-uid","errorCode":null,"errorMessage":"to variable(%s) should only expand to 1 uid","messagePattern":"to variable\\((.+?)\\) should only expand to 1 uid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/query.go","lineNumber":1796,"sourceCode":"\t\t}\n\t\tif uidVar.Uids != nil && len(uidVar.Uids.Uids) > 0 {\n\t\t\tif len(uidVar.Uids.Uids) > 1 {\n\t\t\t\treturn errors.Errorf(\"from variable(%s) should only expand to 1 uid\", fromVar)\n\t\t\t}\n\t\t\tsg.Params.From = uidVar.Uids.Uids[0]\n\t\t}\n\t}\n\n\tif sg.Params.ShortestPathArgs.To != nil && len(sg.Params.ShortestPathArgs.To.NeedsVar) > 0 {\n\t\ttoVar := sg.Params.ShortestPathArgs.To.NeedsVar[0].Name\n\t\tuidVar, ok := mp[toVar]\n\t\tif !ok {\n\t\t\treturn errors.Errorf(\"value of to var(%s) should have already been populated\",\n\t\t\t\ttoVar)\n\t\t}\n\t\tif uidVar.Uids != nil && len(uidVar.Uids.Uids) > 0 {\n\t\t\tif len(uidVar.Uids.Uids) > 1 {\n\t\t\t\treturn errors.Errorf(\"to variable(%s) should only expand to 1 uid\", toVar)\n\t\t\t}\n\t\t\tsg.Params.To = uidVar.Uids.Uids[0]\n\t\t}\n\t}\n\treturn nil\n}\n\n// fillVars reads the value corresponding to a variable from the map mp and stores it inside\n// SubGraph. This value is then later used for execution of the SubGraph.\nfunc (sg *SubGraph) fillVars(mp map[string]varValue) error {\n\tif sg.Params.Alias == \"shortest\" {\n\t\tif err := sg.fillShortestPathVars(mp); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvar lists []*pb.List\n\t// Go through all the variables in NeedsVar and see if we have a value for them in the map. If","sourceCodeStart":1778,"sourceCodeEnd":1814,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/query/query.go#L1778-L1814","documentation":"The 'to' endpoint of a shortest-path query must resolve to exactly one node. When supplied via a variable, Dgraph checks the variable's UID list length and throws this error if it contains more than one UID, since a path to multiple destinations is ambiguous.","triggerScenarios":"shortest(..., to: var(t)) where var(t) matched multiple nodes, e.g. 't as var(func: eq(type, \"Person\"))' returning several UIDs, or a variable accumulated UIDs across multiple matches.","commonSituations":"Overly broad filter on the destination variable; variable reused from a list-producing clause; expecting implicit first-node selection.","solutions":["Narrow the destination variable to a single node with a unique filter (eq on unique predicate, or first: 1)","Replace var(t) with a literal UID when the destination is known","Verify the emitting clause alone returns exactly one node","Split the query if multiple destination paths are genuinely needed (one shortest per destination)"],"exampleFix":"// before: multiple destinations\nt as var(func: eq(type, \"Person\"))\np(func: uid(0x1)) { shortest(to: var(t)) { uid } }\n// after: single destination\nt as var(func: eq(email, \"bob@example.com\"))\np(func: uid(0x1)) { shortest(to: var(t)) { uid } }","handlingStrategy":"validation","validationCode":"if countNodes(toEmittingClause) != 1 {\n    return fmt.Errorf(\"to-variable must resolve to exactly one node\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"should only expand to 1 uid\") && strings.Contains(err.Error(), \"to\") {\n    return fmt.Errorf(\"to-variable ambiguous; narrow the filter: %w\", err)\n}","preventionTips":["Use a unique predicate filter for the destination variable","Add first: 1 to force a single destination","Run one shortest-path query per destination when multiple targets are needed"],"tags":["dgraph","query","shortest-path","variables"],"backgroundTag":"shortest-path-ambiguous-variable","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}