iOfficeAI/OfficeCLI · error · ArgumentException
unknown diagram layout '{layout}'. Valid: {string.Join(", ",
Error message
unknown diagram layout '{layout}'. Valid: {string.Join(", ", Layouts)}. What it means
Thrown by MermaidImageRenderer.ComposeSource (MermaidImageRenderer.cs:134) when a non-null layout value is not in the accepted Layouts set {dagre, elk} (case-insensitive). dagre is mermaid's default layered layout; elk requires the ESM elk loader registered at render time. Unknown layout values are rejected before frontmatter injection.
Source
Thrown at src/officecli/Core/Diagram/MermaidImageRenderer.cs:134
/// <c>--- config: … ---</c> frontmatter block, so they render AND round-trip
/// (the composed source is what gets stamped into alt-text). Returns the
/// source unchanged when no option is set. Rejects unknown values with a
/// message listing the valid ones. When the source already carries its own
/// frontmatter or an <c>%%{init}%%</c> directive, the source wins and the
/// options are ignored (caller may warn) — merging into an existing block is
/// out of scope and would risk producing a malformed document.
/// </summary>
public static string ComposeSource(string mermaid, string? theme, string? layout, string? look)
{
theme = string.IsNullOrWhiteSpace(theme) ? null : theme.Trim();
layout = string.IsNullOrWhiteSpace(layout) ? null : layout.Trim();
look = string.IsNullOrWhiteSpace(look) ? null : look.Trim();
if (theme == null && layout == null && look == null) return mermaid;
if (theme != null && !Themes.Contains(theme))
throw new ArgumentException($"unknown diagram theme '{theme}'. Valid: {string.Join(", ", Themes)}.");
if (layout != null && !Layouts.Contains(layout))
throw new ArgumentException($"unknown diagram layout '{layout}'. Valid: {string.Join(", ", Layouts)}.");
if (look != null && !Looks.Contains(look))
throw new ArgumentException($"unknown diagram look '{look}'. Valid: classic, handDrawn.");
var lead = mermaid.TrimStart();
if (lead.StartsWith("---", StringComparison.Ordinal) || lead.StartsWith("%%{", StringComparison.Ordinal))
return mermaid; // source already declares config — do not double-inject
var sb = new StringBuilder("---\nconfig:\n");
if (theme != null) sb.Append(" theme: ").Append(theme.ToLowerInvariant()).Append('\n');
if (layout != null) sb.Append(" layout: ").Append(layout.ToLowerInvariant()).Append('\n');
// look's canonical mermaid spelling is camelCase handDrawn; normalize.
if (look != null)
sb.Append(" look: ")
.Append(look.Equals("handdrawn", StringComparison.OrdinalIgnoreCase) ? "handDrawn" : "classic")
.Append('\n');
sb.Append("---\n").Append(mermaid);
return sb.ToString();
}View on GitHub (pinned to 1ced45e900)
Solutions
- Use one of: dagre (default layered) or elk (requires ESM elk loader).
- Leave layout unset to use mermaid's default (dagre).
- For elk, ensure the render path uses the ESM build (it does automatically when layout=elk).
Example fix
// before layout=breadthfirst // after layout=elk
Defensive patterns
Strategy: validation
Validate before calling
static readonly HashSet<string> ValidLayouts = new(StringComparer.OrdinalIgnoreCase) { "dagre","elk" };
static string ValidateLayout(string layout) => ValidLayouts.Contains(layout ?? "") ? layout : throw new ArgumentException($"unknown layout '{layout}'"); Type guard
static bool IsValidLayout(string layout) => ValidLayouts.Contains(layout ?? "");
Try / catch
try { MermaidImageRenderer.ComposeSource(mermaid, null, layout, null); }
catch (ArgumentException ex) when (ex.Message.Contains("unknown diagram layout"))
{ /* default to null (dagre) or pick dagre/elk */ } Prevention
- Use mermaid layout ids (dagre, elk), not Cytoscape names (cose, breadthfirst).
- Leave layout null for mermaid's default (dagre).
- For elk, the render path automatically uses the ESM elk loader.
When it happens
Trigger: Setting a diagram layout to 'breadthfirst', 'cose', 'circle', 'grid', 'force', or any value outside {dagre, elk}.
Common situations: Confusing mermaid's layouts with Cytoscape/d3 layout names; passing 'tree' or 'hierarchical' which are not mermaid layout ids; expecting a layout that requires a plugin not loaded.
Related errors
- diagram type '{kind}' is not supported yet (currently: flowc
- diagram has no nodes — the mermaid source has no node/edge s
- unknown diagram theme '{theme}'. Valid: {string.Join(", ", T
- unknown diagram look '{look}'. Valid: classic, handDrawn.
- failed to start mmdc.
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/5761e0680cf6d999.
Report an issue: GitHub.