d2lang/d2 · error
board %v not found
Error message
board %v not found
What it means
d2oracle.Create can edit a nested board only if GetBoardGraph can locate it in the multi-board graph. When boardPath names a board that does not exist, boardG is nil and Create returns this error instead of producing an edit operation.
Source
Thrown at d2oracle/edit.go:41
)
type OutsideScopeError struct{}
func (e OutsideScopeError) Error() string {
return "operation would modify AST outside of given scope"
}
func Create(g *d2graph.Graph, boardPath []string, key string) (_ *d2graph.Graph, newKey string, err error) {
defer xdefer.Errorf(&err, "failed to create %#v", key)
boardG := g
baseAST := g.AST
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 nil, "", fmt.Errorf("board %v not found", boardPath)
}
// TODO beter name
baseAST = boardG.BaseAST
if baseAST == nil {
return nil, "", fmt.Errorf("board %v cannot be modified through this file", boardPath)
}
}
newKey, edge, err := generateUniqueKey(boardG, key, nil, nil)
if err != nil {
return nil, "", err
}
if edge {
err = _set(boardG, baseAST, key, nil, nil)
} else {
err = _set(boardG, baseAST, newKey, nil, nil)
}View on GitHub (pinned to 0d69dca6f5)
Solutions
- Validate the board exists first with GetBoardGraph(g, boardPath) before calling Create
- Match boardPath names exactly to declared layers/scenarios/steps in the compiled graph
- Pass nil/empty boardPath to edit the root board instead
- Recompile the full multi-board graph so all boards are present in g
Example fix
// before
op, err := d2oracle.Create(g, []string{"layers", "newLayer"}, "x")
// after
if d2oracle.GetBoardGraph(g, []string{"layers", "newLayer"}) == nil {
return errors.New("board does not exist; create it first")
}
op, err := d2oracle.Create(g, []string{"layers", "newLayer"}, "x") Defensive patterns
Strategy: validation
Validate before calling
if len(boardPath) > 0 && d2oracle.GetBoardGraph(g, boardPath) == nil {
return fmt.Errorf("board %v does not exist", boardPath)
} Type guard
func boardExists(g *d2graph.Graph, boardPath []string) bool {
return len(boardPath) == 0 || d2oracle.GetBoardGraph(g, boardPath) != nil
} Try / catch
op, _, err := d2oracle.Create(g, boardPath, name)
if err != nil && strings.Contains(err.Error(), "board") && strings.Contains(err.Error(), "not found") {
return fmt.Errorf("create the board before editing: %w", err)
} Prevention
- Check GetBoardGraph for nil before any oracle edit on nested boards
- Keep boardPath derived from the compiled graph's actual board structure
- Recompile the full graph after creating/renaming boards so oracle sees them
When it happens
Trigger: Calling d2oracle.Create(g, boardPath, name) where boardPath is a non-empty slice whose board cannot be found via GetBoardGraph — wrong board names, board not compiled into g, or board declared in another file.
Common situations: Oracle-based tooling (editors, generators) targeting layers/scenarios/steps after they were renamed; building boardPath from user input without validating board existence; boards loaded from separate files absent from g.
Related errors
- board "%v" not found
- expected "shadow" to be true or false
- expected "3d" to be true or false
- expected "multiple" to be true or false
- expected "font-size" to be a number between 8 and 100
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/ea775665977f167a.
Report an issue: GitHub.