{"record":{"id":"4503c9635dc31ba7","repo":"d2lang/d2","slug":"parent-can-only-be-used-in-the-beginning-of-pa","errorCode":null,"errorMessage":"parent \"_\" can only be used in the beginning of paths, e.g. \"_.x\"","messagePattern":"parent \"_\" can only be used in the beginning of paths, e\\.g\\. \"_\\.x\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2graph/d2graph.go","lineNumber":804,"sourceCode":"\t\t\t\t\treferencesActor = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\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","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2graph/d2graph.go#L786-L822","documentation":"In d2 path resolution, the `_` token means 'parent'. It is only meaningful as a leading token chain at the start of a path (e.g. `_.x`, `_._.x`). A `_` appearing after a normal identifier is ambiguous, so resolution fails with this error.","triggerScenarios":"Resolving/compiling a path such as `a._.b` or `x.y._` where `_` appears at index > 0 and the previous token is not `_` — e.g. referencing `a._.b` inside a map key or via d2oracle paths.","commonSituations":"Writing relative references like `parent.child._.other` assuming `_` works anywhere in the path; tools generating paths programmatically appending `_` mid-path; misunderstanding that `_` is only a prefix operator.","solutions":["Move all `_` tokens to the beginning of the path: use `_.a.b` instead of `a._.b`.","If you meant the object literally named with an underscore path, restructure so the reference is relative from the current scope, e.g. write `_.a` at the right nesting level.","If the target is absolute, use a full path from root instead of mixing `_` mid-path.","Quote the identifier if you actually meant a literal `_` character as part of a name."],"exampleFix":"// before\na._.b\n// after\n_.a.b","handlingStrategy":"validation","validationCode":"func validParentPath(path string) bool {\n  segs := strings.Split(path, \".\")\n  for i, s := range segs {\n    if s == \"_\" && i != 0 && segs[i-1] != \"_\" { return false }\n  }\n  return true\n}","typeGuard":"func hasValidUnderscoreUse(ida []string) bool {\n  for i, id := range ida {\n    if id == \"_\" && i != 0 && ida[i-1] != \"_\" { return false }\n  }\n  return true\n}","tryCatchPattern":"obj, ida, err := g.MiddlePath(obj, ida)\nif err != nil && strings.Contains(err.Error(), `parent \"_\"`) {\n  // rewrite the path with _ tokens at the front and retry\n}","preventionTips":["Only use `_` as a leading path prefix.","Never interleave `_` between normal identifiers.","Quote identifiers if you mean a literal underscore-named segment."],"tags":["d2","path-resolution","syntax"],"backgroundTag":"invalid-parent-reference","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}