d2lang/d2 · error
not found
Error message
not found
What it means
ReparentIDDelta looks up the object being reparented via boardG.Root.HasChild(d2graph.Key(mk.Key)). If the board's root has no child matching the parsed key, the operation cannot proceed and it returns the bare error 'not found'. This is a lookup failure on the object to be moved, not on the destination.
Source
Thrown at d2oracle/edit.go:2480
func ReparentIDDelta(g *d2graph.Graph, boardPath []string, key, parentKey string) (string, error) {
mk, err := d2parser.ParseMapKey(key)
if err != nil {
return "", err
}
boardG := g
if len(boardPath) > 0 {
// When compiling a nested board, we can read from boardG but only write to baseBoardG
boardG = GetBoardGraph(g, boardPath)
if boardG == nil {
return "", fmt.Errorf("board %v not found", boardPath)
}
}
obj, ok := boardG.Root.HasChild(d2graph.Key(mk.Key))
if !ok {
return "", errors.New("not found")
}
parent := boardG.Root
if parentKey != "" {
mk2, err := d2parser.ParseMapKey(parentKey)
if err != nil {
return "", err
}
parent, ok = boardG.Root.HasChild(d2graph.Key(mk2.Key))
if !ok {
return "", errors.New("not found")
}
}
prevParent := obj.Parent
obj.Parent = parent
id := obj.AbsID()
obj.Parent = prevParentView on GitHub (pinned to 0d69dca6f5)
Solutions
- Verify objKey exists on the target board before calling: g.Root.HasChild(d2graph.Key(mk)) returns true.
- Check that boardPath points at the board that actually contains the object; pass the correct board path.
- Re-fetch the latest graph (d2lib.Compile) and rebuild the key; the object may have been renamed or deleted.
- Normalize the key with d2parser.ParseMapKey and compare AbsID() against candidates to catch formatting/whitespace mismatches.
Example fix
// before
delta, err := d2oracle.ReparentIDDelta(graph.Id, mk, "child", "newParent") // key missing: "not found"
// after
obj, ok := boardG.Root.HasChild(d2graph.Key(mk.Key))
if !ok {
return fmt.Errorf("object %s not found on board %v", objKey, boardPath)
}
delta, err := d2oracle.ReparentIDDelta(graph.Id, mk, "child", "newParent") Defensive patterns
Strategy: validation
Validate before calling
mk, err := d2parser.ParseMapKey(objKey)
if err != nil { return err }
boardG, err := resolveBoard(g, boardPath)
if err != nil { return err }
if _, ok := boardG.Root.HasChild(d2graph.Key(mk.Key)); !ok {
return fmt.Errorf("object %q does not exist on board %v", objKey, boardPath)
} Type guard
func objectExists(g *d2graph.Graph, boardPath string, key string) bool {
mk, err := d2parser.ParseMapKey(key)
if err != nil { return false }
bg, err := resolveBoard(g, boardPath)
if err != nil { return false }
_, ok := bg.Root.HasChild(d2graph.Key(mk.Key))
return ok
} Try / catch
delta, err := d2oracle.ReparentIDDelta(id, mk, objKey, parentKey)
if err != nil {
if err.Error() == "not found" {
return fmt.Errorf("object %q not found on board %v; refresh graph and retry", objKey, boardPath)
}
return err
} Prevention
- Validate keys with Root.HasChild before reparenting
- Keep boardPath consistent with where the key lives
- Refresh/recompile the graph after other clients' edits
- Derive keys from AbsID() instead of hardcoding
When it happens
Trigger: Calling d2oracle.ReparentIDDelta with a boardPath whose board exists, but whose objKey parses to a key that does not exist as a direct/descendant child of that board's Root (typo, wrong board, object already deleted, or key belonging to a different board).
Common situations: Passing a key scoped to the top-level graph while boardPath points at a sub-board; reparenting an object that a previous delta already deleted; stale keys after a rename in another client.
Related errors
- moving across scopes isn't supported for edges
- edgeKey must be an edge
- edgeKey must refer to an existing edge
- cannot generate unique key for edge chain
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/2d2c032ae1ad9bb0.
Report an issue: GitHub.