iOfficeAI/OfficeCLI · error · ArgumentException

sequence diagram has no participants.

Error message

sequence diagram has no participants.

What it means

SequenceLayout.Layout computes participant columns and lifelines from d.Participants; with an empty list there is nothing to lay out, so it throws ArgumentException. This is a contract violation by the caller — a SequenceDiagram must declare at least one participant before layout.

Source

Thrown at src/officecli/Core/Diagram/SequenceLayout.cs:101

                {
                    From = mm.Groups[1].Value,
                    To = mm.Groups[3].Value,
                    Label = mm.Groups[4].Value.Trim(),
                    Dashed = op.StartsWith("--"),
                    Arrow = op.Contains('>') || op.Contains('x') || op.Contains(')'),
                });
            }
        }
        return d;
    }

    public static LaidOutGraph Layout(SequenceDiagram d)
    {
        const double boxH = 1.1, top = 0.8, hGap = 1.4, row = 1.15;
        var order = d.Participants;
        var lo = new LaidOutGraph { FontScale = 1.0 };
        if (order.Count == 0)
            throw new ArgumentException("sequence diagram has no participants.");

        // participant x positions (left, width) + lifeline centre
        var left = new Dictionary<string, double>();
        var width = new Dictionary<string, double>();
        var cxOf = new Dictionary<string, double>();
        double cur = 0.8;
        foreach (var p in order)
        {
            double w = Math.Max(2.4, TextWidth(p.Label) + 1.0);
            left[p.Id] = cur; width[p.Id] = w; cxOf[p.Id] = cur + w / 2;
            cur += w + hGap;
        }
        double bodyTop = top + boxH + 0.9;
        double bottom = bodyTop + Math.Max(1, d.Messages.Count) * row + 0.6;
        lo.SlideWidthCm = Math.Max(cur - hGap + 0.8, 12.0);
        lo.SlideHeightCm = bottom + 0.8;

        // participant boxes + lifelines

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Ensure at least one participant is added to the SequenceDiagram before calling Layout.
  2. If parsing user input, synthesize participants from message sender/receiver when none are declared explicitly.
  3. Validate Participants.Count > 0 before invoking Layout and emit a clear upstream error.

Example fix

// before
var d = new SequenceDiagram();
d.Messages.Add(new Msg("A", "B", "hi"));
var laid = SequenceLayout.Layout(d); // throws — no participants

// after
var d = new SequenceDiagram();
d.Participants.Add(new Participant("A", "Alice"));
d.Participants.Add(new Participant("B", "Bob"));
d.Messages.Add(new Msg("A", "B", "hi"));
var laid = SequenceLayout.Layout(d);
Defensive patterns

Strategy: validation

Validate before calling

if (diagram.Participants == null || diagram.Participants.Count == 0)
    throw new ArgumentException("Cannot lay out a sequence diagram with no participants; add participants or synthesize them from message senders/receivers.");

Type guard

static bool IsLayableSequence(SequenceDiagram d)
    => d != null && d.Participants is { Count: > 0 };

Try / catch

try { laid = SequenceLayout.Layout(d); }
catch (ArgumentException ex) when (ex.Message.Contains("no participants", StringComparison.Ordinal))
{
    // synthesize participants from messages, then retry
    foreach (var m in d.Messages) { EnsureParticipant(d, m.From); EnsureParticipant(d, m.To); }
    laid = SequenceLayout.Layout(d);
}

Prevention

When it happens

Trigger: A caller built a SequenceDiagram (e.g. from parsed text or an API) and added messages without ever adding a participant, then passed it to SequenceLayout.Layout. order.Count == 0 trips the guard before any positioning math.

Common situations: Parsing a sequence block that has only messages with inline actor syntax but the parser didn't synthesize participants; an empty/whitespace sequence diagram body; a programmatic builder that forgot AddParticipant.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/478c9c60f95b31f1. Report an issue: GitHub.