{"record":{"id":"359249165cc4ef1d","repo":"d2lang/d2","slug":"newdst-not-found","errorCode":null,"errorMessage":"newDst not found","messagePattern":"newDst not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2oracle/edit.go","lineNumber":205,"sourceCode":"\tvar dst *d2graph.Object\n\tif srcKey != nil {\n\t\tsrcmk, err := d2parser.ParseMapKey(*srcKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsrc, ok = boardG.Root.HasChild(d2graph.Key(srcmk.Key))\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"newSrc not found\")\n\t\t}\n\t}\n\tif dstKey != nil {\n\t\tdstmk, err := d2parser.ParseMapKey(*dstKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdst, ok = boardG.Root.HasChild(d2graph.Key(dstmk.Key))\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"newDst not found\")\n\t\t}\n\t}\n\n\trefs := edge.References\n\tif baseAST != g.AST {\n\t\trefs = GetWriteableEdgeRefs(edge, baseAST)\n\t\tif len(refs) == 0 || refs[0].ScopeAST != baseAST {\n\t\t\t// TODO null\n\t\t\treturn nil, OutsideScopeError{}\n\t\t}\n\t}\n\tref := refs[0]\n\n\t// for loops where only one end is changing, node is always ensured\n\tif edge.Src != edge.Dst && (srcKey == nil || dstKey == nil) {\n\t\tvar refEdges []*d2ast.Edge\n\t\tfor _, ref := range refs {\n\t\t\trefEdges = append(refEdges, ref.Edge)","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2oracle/edit.go#L187-L223","documentation":"Same failure mode as newSrc but for the destination: ReconnectEdge parsed `dstKey` and could not find a matching object under the board's root. The rewire is aborted so the graph is never left with a dangling destination.","triggerScenarios":"Calling d2oracle.ReconnectEdge with `dstKey` for a non-existent node: typo, dst node deleted, dst in another board than boardPath, or unquoted special characters in the ID path.","commonSituations":"Reconnecting an edge to a target the user just typed that was never created; tooling that assumes ReconnectEdge auto-creates endpoints (it does not for the dst lookup); nested board sketches where the target exists only on the root board.","solutions":["Create the destination node first via d2oracle.Create, then call ReconnectEdge.","Pre-validate dstKey with g.Root.HasChild on the parsed key.","Pass the destination node's AbsID() as dstKey.","Make sure boardPath matches the board where the dst node actually lives."],"exampleFix":"// before\ng, err = d2oracle.ReconnectEdge(g, []string{\"layers.x\"}, \"a -> b\", nil, &newDst) // newDst missing in board\n// after\nif _, ok := boardG.Root.HasChild([]string{\"c\"}); !ok {\n    g, _, err = d2oracle.Create(g, nil, \"c\", nil)\n}\ng, err = d2oracle.ReconnectEdge(g, []string{\"layers.x\"}, \"a -> b\", nil, &newDst)","handlingStrategy":"validation","validationCode":"dstmk, err := d2parser.ParseMapKey(newDst)\nif err != nil { return err }\nif _, ok := g.Root.HasChild(d2graph.Key(dstmk.Key)); !ok {\n    g, _, err = d2oracle.Create(g, nil, newDst, nil)\n    if err != nil { return err }\n}","typeGuard":"func nodeExists(g *d2graph.Graph, id string) bool {\n    mk, err := d2parser.ParseMapKey(id)\n    if err != nil { return false }\n    _, ok := g.Root.HasChild(d2graph.Key(mk.Key))\n    return ok\n}","tryCatchPattern":"g2, err := d2oracle.ReconnectEdge(g, boardPath, key, nil, &newDst)\nif err != nil && err.Error() == \"newDst not found\" {\n    g, _, err = d2oracle.Create(g, nil, newDst, nil)\n    if err != nil { return err }\n    g2, err = d2oracle.ReconnectEdge(g, boardPath, key, nil, &newDst)\n}","preventionTips":["Ensure the destination node exists in the same board passed via boardPath","Use AbsID() for endpoint keys","Auto-create missing endpoints as a standard pre-step in rewire tooling","Validate dstKey right after user input, before graph mutation"],"tags":["graph","edge","node-lookup","d2"],"backgroundTag":"node-not-found","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}