iOfficeAI/OfficeCLI · warning · MermaidSyntaxException
mermaid syntax error: {ExtractMermaidMessage(dom)} (fix the
Error message
mermaid syntax error: {ExtractMermaidMessage(dom)}
(fix the mermaid source, or use render=native for the built-in subset). What it means
The chrome DOM dump contained <title>MMDSYNTAX</title>, the authoritative signal that mermaid.parse() rejected the source. Because mermaid still injects its red 'Syntax error' bomb graphic into the DOM on failure, the code keys off the title rather than the presence of an <svg>. ExtractMermaidMessage pulls mermaid's captured error text. This is bad input, surfaced as MermaidSyntaxException.
Source
Thrown at src/officecli/Core/Diagram/MermaidImageRenderer.cs:373
// a plain source keeps the offline-cached UMD path unchanged.
var html = SourceNeedsEsm(mermaid)
? BuildHtmlEsm(mermaid, SourceNeedsElk(mermaid), SafeBackground(background))
: BuildHtml(mermaid, ResolveMermaidJsRef(), SafeBackground(background));
var htmlPath = Path.Combine(Path.GetTempPath(), $"ocli_mmd_{Guid.NewGuid():N}.html");
File.WriteAllText(htmlPath, html);
try
{
var dom = HtmlScreenshot.DumpDom(htmlPath)
?? throw new InvalidOperationException("headless browser produced no output.");
// The <title> is the AUTHORITATIVE outcome — not the presence of an <svg>.
// On a syntax error mermaid.parse() rejects (we capture the message) but
// STILL injects its red "Syntax error" bomb graphic into the DOM anyway
// (suppressErrorRendering doesn't stop it). So a viewBox is present even on
// failure; keying off the svg would screenshot the bomb and "succeed".
// Trust the title: MMDREADY = real render, MMDSYNTAX = bad input, else infra.
if (dom.Contains("<title>MMDSYNTAX</title>", StringComparison.Ordinal))
throw new MermaidSyntaxException(
"mermaid syntax error: " + ExtractMermaidMessage(dom)
+ "\n(fix the mermaid source, or use render=native for the built-in subset).");
if (!dom.Contains("<title>MMDREADY</title>", StringComparison.Ordinal))
throw new InvalidOperationException(
dom.Contains("<title>MMDERR</title>", StringComparison.Ordinal)
? "mermaid failed to render: " + ExtractMermaidMessage(dom)
: "mermaid produced no diagram (mermaid.js failed to load or the render timed out).");
var (w, h) = ParseSvgSize(dom);
if (w <= 0 || h <= 0)
throw new InvalidOperationException("mermaid rendered but produced no measurable svg viewBox.");
var pngPath = Path.ChangeExtension(htmlPath, ".png");
if (!HtmlScreenshot.CaptureChromeSized(htmlPath, pngPath,
(int)Math.Ceiling(w) + 2, (int)Math.Ceiling(h) + 2))
throw new InvalidOperationException("headless screenshot failed.");
return pngPath;
}View on GitHub (pinned to 1ced45e900)
Solutions
- Read the extracted mermaid message — it names the parse failure and usually the line.
- Correct the cited syntax, or simplify to a supported diagram type.
- If valid for newer mermaid, update the cached/downloaded mermaid.js (clear the cache so ResolveMermaidJsRef fetches a newer build).
- Use render=native if the diagram is within the built-in subset.
Example fix
// before — unsupported syntax in bundled mermaid.js sequenceDiagram Alice>>Bob: hi // '>>' is not a valid arrow // after sequenceDiagram Alice->>Bob: hi
Defensive patterns
Strategy: validation
Validate before calling
// Reuse the renderer's own syntax signature set for a cheap pre-check
static bool MayBeSyntaxBroken(string src)
=> src.Contains(" >> ") == false /* example guard for arrow typos */;
// Best: call mermaid.parse() in-page and read the title before committing to a screenshot. Try / catch
try { png = MermaidImageRenderer.RenderViaChrome(mermaid, bg); }
catch (MermaidSyntaxException ex)
{
// bad input — report, do not fall back
result.AddError("mermaid", ex.Message);
} Prevention
- Test mermaid snippets with the same mermaid.js version before batch use.
- Treat MermaidSyntaxException as user input, not infrastructure.
- Keep the cached mermaid.js current with the syntax you rely on.
When it happens
Trigger: The HTML harness calls mermaid.parse() on the source; it rejects (throws) and the page sets document.title to MMDSYNTAX with the error text. Happens for malformed mermaid: unknown diagram type, bad directive, unmatched brackets, reserved-word collisions.
Common situations: Source uses syntax or a diagram type unsupported by the bundled mermaid.js version; copy-paste damage; a node id colliding with a mermaid reserved word; frontmatter YAML typo.
Related errors
- mermaid syntax error: {msg} (fix the mermaid source, or use
- 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 layout '{layout}'. Valid: {string.Join(", ",
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/fa132eb81f3b6989.
Report an issue: GitHub.