d2lang/d2 · error

board at path %v not found

Error message

board at path %v not found

What it means

d2oracle.GetChildrenIDs first resolves boardPath through GetBoardGraph; a nil result means no board in the graph matches the path, so it returns "board at path %v not found". The library validates the board path before touching any objects. It signals that the caller's board navigation input is invalid, not that a specific object is missing.

Source

Thrown at d2oracle/get.go:90

				if len(boardPath) > 1 {
					if ReplaceBoardNode(n.MapKey.Value.Map, ast2, boardPath[1:]) {
						return true
					}
				} else {
					n.MapKey.Value.Map.Nodes = ast2.Nodes
					return true
				}
			}
		}
	}

	return false
}

func GetChildrenIDs(g *d2graph.Graph, boardPath []string, absID string) (ids []string, _ error) {
	g = GetBoardGraph(g, boardPath)
	if g == nil {
		return nil, fmt.Errorf("board at path %v not found", boardPath)
	}

	mk, err := d2parser.ParseMapKey(absID)
	if err != nil {
		return nil, err
	}
	obj, ok := g.Root.HasChild(d2graph.Key(mk.Key))
	if !ok {
		return nil, fmt.Errorf("%v not found", absID)
	}

	for _, ch := range obj.ChildrenArray {
		ids = append(ids, ch.AbsID())
	}

	return ids, nil
}

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Verify the board path exists in the current graph (list boards from the D2 script) and fix the spelling/structure.
  2. Pass an empty boardPath ([]string{} or nil) if you actually want children on the root board.
  3. Ensure path elements match exactly, including underscores vs dashes and casing.
  4. Regenerate the path programmatically from the graph instead of hard-coding it.

Example fix

// before
ids, err := d2oracle.GetChildrenIDs(g, []string{"layers", "auth"}, "root.db")
// after
ids, err := d2oracle.GetChildrenIDs(g, []string{"layers", "authLayer"}, "root.db") // board actually defined in script
Defensive patterns

Strategy: validation

Validate before calling

if d2oracle.GetBoardGraph(g, boardPath) == nil {
	return nil, fmt.Errorf("board %v does not exist; fix boardPath before GetChildrenIDs", boardPath)
}
ids, err := d2oracle.GetChildrenIDs(g, boardPath, absID)

Type guard

func boardResolvable(g *d2graph.Graph, boardPath []string) bool {
	return d2oracle.GetBoardGraph(g, boardPath) != nil
}

Try / catch

ids, err := d2oracle.GetChildrenIDs(g, boardPath, absID)
if err != nil {
	if strings.Contains(err.Error(), "board at path") {
		ids, err = d2oracle.GetChildrenIDs(g, nil, absID) // fallback to root board
	}
	if err != nil {
		return err
	}
}

Prevention

When it happens

Trigger: Calling d2oracle.GetChildrenIDs(g, boardPath, absID) where boardPath does not resolve to an existing board, e.g. GetChildrenIDs(g, []string{"layers.layer1"}, "x.y") when the graph has no such board.

Common situations: Hard-coded board path from another project/diagram; board path built by joining with '.' then splitting incorrectly; referencing a board inside a scenario/step that has not been defined; stale path after refactoring the D2 script.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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