d2lang/d2 · error
no layout resolver configured for layout engine %q
Error message
no layout resolver configured for layout engine %q
What it means
d2lib's getLayout resolves the layout engine name through an optional LayoutResolver function in CompileOptions. If a Layout name was provided but no LayoutResolver was configured, there is no way to map the name to an implementation, so compilation fails with this error.
Source
Thrown at d2lib/d2.go:199
}
previous := geometry
for i, l := range g.Steps {
ld, stepGeometry, err := compileBoard(ctx, l, compileOpts, renderOpts, previous, i+1 < len(g.Steps))
if err != nil {
return nil, nil, err
}
d.Steps = append(d.Steps, ld)
previous = stepGeometry
}
return d, geometry, nil
}
func getLayout(opts *CompileOptions) (d2graph.LayoutGraph, error) {
if opts.Layout == nil {
return nil, errors.New("no available layout")
}
if opts.LayoutResolver == nil {
return nil, fmt.Errorf("no layout resolver configured for layout engine %q", *opts.Layout)
}
return opts.LayoutResolver(*opts.Layout)
}
func getEdgeRouter(opts *CompileOptions) (d2graph.RouteEdges, error) {
if opts.Layout != nil && opts.RouterResolver != nil {
router, err := opts.RouterResolver(*opts.Layout)
if err != nil {
return nil, err
}
if router != nil {
return router, nil
}
}
return d2layouts.DefaultRouter, nil
}
// applyConfigs applies the configs read from D2 and applies it to passed in optsView on GitHub (pinned to 0d69dca6f5)
Solutions
- Set CompileOptions.LayoutResolver to a resolver such as d2plugin.NativeResolver or your custom mapping function
- Omit Layout to use the default path instead of naming an engine you cannot resolve
- Use the higher-level d2lib helpers that wire the resolver automatically
Example fix
// before
opts := &d2lib.CompileOptions{Layout: &layoutName}
// after
opts := &d2lib.CompileOptions{
Layout: &layoutName,
LayoutResolver: d2plugin.NativeResolver,
} Defensive patterns
Strategy: validation
Validate before calling
if opts.Layout != nil && opts.LayoutResolver == nil {
return errors.New("Layout set but LayoutResolver is nil")
} Type guard
func optionsReady(opts *d2lib.CompileOptions) bool {
return opts.Layout == nil || opts.LayoutResolver != nil
} Try / catch
if _, err := d2lib.Compile(ctx, input, opts); err != nil {
if strings.Contains(err.Error(), "no layout resolver configured") {
opts.LayoutResolver = d2plugin.NativeResolver
_, err = d2lib.Compile(ctx, input, opts)
}
return err
} Prevention
- Always pair CompileOptions.Layout with a LayoutResolver
- Use helper constructors that wire resolvers automatically
- Centralize CompileOptions construction in one tested function
When it happens
Trigger: Calling d2lib.Compile with CompileOptions.Layout set to a non-nil engine name (e.g. "dagre" or "elk") while leaving CompileOptions.LayoutResolver nil.
Common situations: Custom compile setups in embedding code (plugins, LSP tools) that set Layout but forget the resolver; tests constructing CompileOptions manually; copying options structs partially between call sites.
Related errors
- no available layout
- no actors declared in sequence diagram
- dimensions for object label %#v not found
- theme %d not found
- could not find center of %s. Is it declared as an actor?
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/dba0eadb33753b4d.
Report an issue: GitHub.