d2lang/d2 · error
no actors declared in sequence diagram
Error message
no actors declared in sequence diagram
What it means
The sequence diagram layout requires at least one actor (top-level participant shapes). If the graph contains no shapes that qualify as actors, newSequenceDiagram cannot build a diagram and returns this error.
Source
Thrown at d2layouts/d2sequence/sequence_diagram.go:109
queue := []*d2graph.Object{obj}
// Groups may have more nested groups
for len(queue) > 0 {
curr := queue[0]
curr.LabelPosition = go2.Pointer(label.InsideTopLeft.String())
groups = append(groups, curr)
queue = queue[1:]
queue = append(queue, curr.ChildrenArray...)
}
} else {
actors = append(actors, obj)
if obj.IsSequenceDiagram() {
return nil, fmt.Errorf("actors in sequence diagrams cannot themselves be sequence diagrams: %s", obj.AbsID())
}
}
}
if len(actors) == 0 {
return nil, errors.New("no actors declared in sequence diagram")
}
sd := &sequenceDiagram{
messages: messages,
actors: actors,
groups: groups,
spans: nil,
notes: nil,
lifelines: nil,
objectRank: make(map[*d2graph.Object]int),
firstMessage: make(map[*d2graph.Object]*d2graph.Edge),
lastMessage: make(map[*d2graph.Object]*d2graph.Edge),
actorXStep: make([]float64, len(actors)-1),
yStep: MIN_MESSAGE_DISTANCE,
maxActorHeight: 0.,
verticalIndices: make(map[string]int),
}
View on GitHub (pinned to 0d69dca6f5)
Solutions
- Declare at least two participant shapes in the sequence diagram scope.
- Ensure the diagram using seq layout actually contains participant objects (not just connections).
- If seq is set globally, scope it only to the intended nested diagram via near/layout attributes, or switch the board's layout engine to elk/dae for non-sequence boards.
- Check that participants aren't misclassified (e.g. marked as containers/groups).
Example fix
// before
vars: { d2-config: { layout-engine: seq } }
x -> y
// after
vars: { d2-config: { layout-engine: seq } }
a: A
b: B
a -> b Defensive patterns
Strategy: validation
Validate before calling
actors := 0
for _, o := range g.Objects { if isSequenceActor(o) { actors++ } }
if actors == 0 { /* skip seq layout or add participants */ } Type guard
func hasSeqActors(g *d2graph.Graph) bool {
for _, o := range g.Objects { if o.InnerSequenceDiagram() == nil { return true } }
return false
} Try / catch
if err := layoutSequenceDiagram(g); err != nil && strings.Contains(err.Error(), "no actors") {
// fall back to the default layout engine
} Prevention
- Only apply layout: seq to boards containing participant shapes.
- Scope seq layout with near/layout attributes rather than globally.
- Add explicit actor declarations to every sequence diagram.
When it happens
Trigger: Applying layout: seq (near or with d2layout sequence engine) to a graph where the `actors` slice is empty — e.g. a diagram with only edges, or all objects are groups/containers of sequence diagrams.
Common situations: Setting `layout: seq` globally but the board contains a non-sequence subgraph; an empty or edge-only diagram; nested sequence diagrams filtered out by the 'cannot themselves be sequence diagrams' rule leaving zero actors.
Related errors
- could not find center of %s. Is it declared as an actor?
- no available layout
- dimensions for object label %#v not found
- actors in sequence diagrams cannot themselves be sequence di
- no layout resolver configured for layout engine %q
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/da02b68fefd05896.
Report an issue: GitHub.