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 = prevParent

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Verify objKey exists on the target board before calling: g.Root.HasChild(d2graph.Key(mk)) returns true.
  2. Check that boardPath points at the board that actually contains the object; pass the correct board path.
  3. Re-fetch the latest graph (d2lib.Compile) and rebuild the key; the object may have been renamed or deleted.
  4. 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

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


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/2d2c032ae1ad9bb0. Report an issue: GitHub.