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
- Verify the board path exists in the current graph (list boards from the D2 script) and fix the spelling/structure.
- Pass an empty boardPath ([]string{} or nil) if you actually want children on the root board.
- Ensure path elements match exactly, including underscores vs dashes and casing.
- 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
- Validate board paths against the graph before any d2oracle getter call.
- Use nil/empty boardPath for the root board rather than guessing a path.
- Centralize board-path construction in one helper with tests.
- Keep board names in sync between scripts and calling code (rename is a breaking change).
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
- can only set one edge at a time
- edge key must be reserved
- can only delete one edge at a time
- expected "shadow" to be true or false
- expected "3d" to be true or false
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/208e159242cca5f8.
Report an issue: GitHub.