{"record":{"id":"c2d08be336858d20","repo":"d2lang/d2","slug":"parent-cannot-be-used-in-the-root-scope","errorCode":null,"errorMessage":"parent \"_\" cannot be used in the root scope","messagePattern":"parent \"_\" cannot be used in the root scope","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2graph/d2graph.go","lineNumber":807,"sourceCode":"\t\t\t}\n\t\t\tif referencesActor {\n\t\t\t\tobj = objSD\n\t\t\t}\n\t\t}\n\t}\n\n\tresolvedObj = obj\n\tresolvedIDA = ida\n\n\tfor i, id := range ida {\n\t\tif id != \"_\" {\n\t\t\tcontinue\n\t\t}\n\t\tif i != 0 && ida[i-1] != \"_\" {\n\t\t\treturn nil, nil, errors.New(`parent \"_\" can only be used in the beginning of paths, e.g. \"_.x\"`)\n\t\t}\n\t\tif resolvedObj == obj.Graph.Root {\n\t\t\treturn nil, nil, errors.New(`parent \"_\" cannot be used in the root scope`)\n\t\t}\n\t\tif i == len(ida)-1 {\n\t\t\treturn nil, nil, errors.New(`invalid use of parent \"_\"`)\n\t\t}\n\t\tresolvedObj = resolvedObj.Parent\n\t\tresolvedIDA = resolvedIDA[1:]\n\t}\n\n\treturn resolvedObj, resolvedIDA, nil\n}\n\n// TODO: remove edges []edge and scope each edge inside Object.\nfunc (obj *Object) FindEdges(mk *d2ast.Key) ([]*Edge, bool) {\n\tif len(mk.Edges) != 1 {\n\t\treturn nil, false\n\t}\n\tif mk.EdgeIndex.Int == nil {\n\t\treturn nil, false","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2graph/d2graph.go#L789-L825","documentation":"`_` resolves to the parent of the current scope. When the current scope is already the root object, there is no parent, so d2graph rejects the reference with this error during path resolution.","triggerScenarios":"Using `_.x` (or `_.x.y`) at the top level of a d2 file / root scope, where the resolved parent of root does not exist — e.g. a top-level map key like `_.x` or a d2oracle call at root scope.","commonSituations":"Copy-pasting a relative reference from inside a nested block to the top level; macros or templates that emit `_.` prefixes regardless of nesting depth.","solutions":["Remove the `_` prefix and reference `x` directly, since at root scope the name is already unambiguous.","If the reference must be relative, move it inside the nested scope where `_` has a parent to climb.","Use the absolute path from root instead of a parent-relative path."],"exampleFix":"// before (at root scope)\n_.x\n// after\nx","handlingStrategy":"validation","validationCode":"func underscoreAllowedAtRoot(path string) bool { return !strings.HasPrefix(path, \"_.\") } // at root scope, don't use _. prefix","typeGuard":"func isRootScope(obj *d2graph.Object) bool { return obj.Parent == nil }","tryCatchPattern":"if _, _, err := g.MiddlePath(obj, ida); err != nil && strings.Contains(err.Error(), \"root scope\") {\n  ida = ida[1:] // drop the leading _ and retry\n}","preventionTips":["At root scope, reference names directly without `_`.","When templating relative references, check current nesting depth first.","Prefer absolute paths in generated code."],"tags":["d2","path-resolution","scope"],"backgroundTag":"invalid-parent-reference","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}