{"record":{"id":"65f88bd047a71d4d","repo":"iOfficeAI/OfficeCLI","slug":"mermaid-syntax-error-msg-fix-the-mermaid-sourc","errorCode":null,"errorMessage":"mermaid syntax error: {msg} (fix the mermaid source, or use render=native for the built-in subset).","messagePattern":"mermaid syntax error: (.+?) \\(fix the mermaid source, or use render=native for the built-in subset\\)\\.","errorType":"validation","errorClass":"MermaidSyntaxException","httpStatus":null,"severity":"warning","filePath":"src/officecli/Core/Diagram/MermaidImageRenderer.cs","lineNumber":336,"sourceCode":"            using var p = Process.Start(psi)\n                ?? throw new InvalidOperationException(\"failed to start mmdc.\");\n            // Async-drain both streams: the serial stderr-then-stdout reads\n            // interlocked when mmdc filled the stdout pipe first (bounded by\n            // the 120s kill below, but a wasted two minutes per diagram).\n            var errTask = p.StandardError.ReadToEndAsync();\n            var outTask = p.StandardOutput.ReadToEndAsync();\n            if (!p.WaitForExit(120_000))\n            {\n                try { p.Kill(true); } catch { /* best effort */ }\n                throw new InvalidOperationException(\"mmdc timed out after 120s.\");\n            }\n            if (p.ExitCode != 0 || !File.Exists(outPath))\n            {\n                var msg = $\"{errTask.Result}{outTask.Result}\".Trim();\n                // A parse/unknown-type failure is bad input, not a broken mmdc; class\n                // it as syntax so the Add path surfaces it (and does not fall back).\n                if (LooksLikeSyntaxError(msg))\n                    throw new MermaidSyntaxException(\n                        $\"mermaid syntax error: {msg} \"\n                        + \"(fix the mermaid source, or use render=native for the built-in subset).\");\n                throw new InvalidOperationException($\"mmdc failed (exit {p.ExitCode}). {msg}\".Trim());\n            }\n            return outPath;\n        }\n        finally { try { File.Delete(inPath); } catch { /* best effort */ } }\n    }\n\n    // ----- chrome-family browser (mermaid.js in a page → sized screenshot) --------------\n\n    /// <summary>Two chrome passes: dump the DOM to read the diagram's viewBox, then\n    /// screenshot at exactly that size (HiDPI). PNG bakes in the browser's rendering\n    /// so mermaid's foreignObject labels — invisible to Office as SVG — appear.</summary>\n    private static string RenderViaChrome(string mermaid, string? background)\n    {\n        // A styled source (theme/layout/look frontmatter) is rendered by the ESM\n        // build (the UMD global does not render frontmatter, and elk is ESM-only);","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Diagram/MermaidImageRenderer.cs#L318-L354","documentation":"mmdc exited non-zero (or produced no output file) and the combined stderr+stdout matched a known syntax-error signature via LooksLikeSyntaxError (phrases: 'Parse error', 'Lexical error', 'No diagram type detected', 'UnknownDiagramError', 'Expecting '). The renderer reclassifies this as MermaidSyntaxException so the Add path surfaces it as bad input instead of treating it as a broken mmdc and falling back.","triggerScenarios":"Calling the mmdc render path with mermaid source that fails to parse: an unknown diagram type, a malformed directive, a typo in a keyword, or a graph/flowchart with an unmatched bracket. mmdc returns non-zero, no PNG is written, and its stderr contains one of the recognized parse-failure phrases.","commonSituations":"User pastes a mermaid snippet using a diagram type or directive not supported by the installed @mermaid-js/mermaid-cli version; copy-paste introduces a stray character; the source uses newer mermaid syntax than the bundled mmdc supports.","solutions":["Read the {msg} portion: it is mermaid's own parse error with line/column — fix the cited syntax.","If the syntax is valid for a newer mermaid, upgrade @mermaid-js/mermaid-cli (`npm i -g @mermaid-js/mermaid-cli@latest`) and point OFFICECLI_MMDC at it.","If the diagram type isn't supported, switch to render=native for the built-in subset, or simplify the source to a supported type.","Validate the source with `mmdc -i src.mmd -o /tmp/x.png` directly to confirm the parse error reproduces outside this tool."],"exampleFix":"// before — mermaid with a typo / unsupported type\ngraph TD\n  A -->B   C\n\n// after — valid flowchart syntax\ngraph TD\n  A --> B\n  B --> C","handlingStrategy":"validation","validationCode":"// Validate mermaid source against the same parse-failure signatures before rendering\nstatic bool LooksLikeValidMermaid(string src)\n{\n    if (string.IsNullOrWhiteSpace(src)) return false;\n    // Cheap pre-check: must reference a known diagram type keyword\n    var head = src.TrimStart('-', ' ', '\\n', '\\r');\n    return head.Contains(\"graph\", StringComparison.OrdinalIgnoreCase)\n        || head.Contains(\"flowchart\", StringComparison.OrdinalIgnoreCase)\n        || head.Contains(\"sequenceDiagram\", StringComparison.OrdinalIgnoreCase)\n        || head.Contains(\"pie\", StringComparison.OrdinalIgnoreCase);\n}","typeGuard":null,"tryCatchPattern":"try { png = MermaidImageRenderer.Render(mermaid, bg); }\ncatch (MermaidSyntaxException ex)\n{\n    // bad input — surface to the user, do NOT fall back to a different renderer\n    result.AddError(\"mermaid\", ex.Message);\n}","preventionTips":["Treat MermaidSyntaxException as user-input failure: report, don't fall back.","Lint mermaid source with `mmdc -i src.mmd -o /tmp/x.png` before batch rendering.","Keep the bundled/installed mermaid-cli version aligned with the syntax features you use."],"tags":["mermaid","syntax","validation","user-input","mmdc"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}