{"record":{"id":"4be1e735da63c28d","repo":"iOfficeAI/OfficeCLI","slug":"mermaid-rendered-but-produced-no-measurable-svg-vi","errorCode":null,"errorMessage":"mermaid rendered but produced no measurable svg viewBox.","messagePattern":"mermaid rendered but produced no measurable svg viewBox\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Diagram/MermaidImageRenderer.cs","lineNumber":384,"sourceCode":"            // The <title> is the AUTHORITATIVE outcome — not the presence of an <svg>.\n            // On a syntax error mermaid.parse() rejects (we capture the message) but\n            // STILL injects its red \"Syntax error\" bomb graphic into the DOM anyway\n            // (suppressErrorRendering doesn't stop it). So a viewBox is present even on\n            // failure; keying off the svg would screenshot the bomb and \"succeed\".\n            // Trust the title: MMDREADY = real render, MMDSYNTAX = bad input, else infra.\n            if (dom.Contains(\"<title>MMDSYNTAX</title>\", StringComparison.Ordinal))\n                throw new MermaidSyntaxException(\n                    \"mermaid syntax error: \" + ExtractMermaidMessage(dom)\n                    + \"\\n(fix the mermaid source, or use render=native for the built-in subset).\");\n            if (!dom.Contains(\"<title>MMDREADY</title>\", StringComparison.Ordinal))\n                throw new InvalidOperationException(\n                    dom.Contains(\"<title>MMDERR</title>\", StringComparison.Ordinal)\n                    ? \"mermaid failed to render: \" + ExtractMermaidMessage(dom)\n                    : \"mermaid produced no diagram (mermaid.js failed to load or the render timed out).\");\n\n            var (w, h) = ParseSvgSize(dom);\n            if (w <= 0 || h <= 0)\n                throw new InvalidOperationException(\"mermaid rendered but produced no measurable svg viewBox.\");\n\n            var pngPath = Path.ChangeExtension(htmlPath, \".png\");\n            if (!HtmlScreenshot.CaptureChromeSized(htmlPath, pngPath,\n                    (int)Math.Ceiling(w) + 2, (int)Math.Ceiling(h) + 2))\n                throw new InvalidOperationException(\"headless screenshot failed.\");\n            return pngPath;\n        }\n        finally { try { File.Delete(htmlPath); } catch { /* best effort */ } }\n    }\n\n    /// <summary>Cache → one-time download → live CDN. Returns a URL usable as a\n    /// &lt;script src&gt; (a <c>file://</c> for a cached/downloaded copy, else the CDN).</summary>\n    private static string ResolveMermaidJsRef()\n    {\n        try\n        {\n            if (File.Exists(CachedJsPath) && new FileInfo(CachedJsPath).Length > 500_000)\n                return new Uri(CachedJsPath).AbsoluteUri;","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Diagram/MermaidImageRenderer.cs#L366-L402","documentation":"The DOM carried the success marker <title>MMDREADY</title> (mermaid parsed and rendered), but ParseSvgSize returned a width or height <= 0 — the injected SVG had no measurable viewBox/size. The code treats a real render with no geometry as a failure because the second pass needs exact pixel dimensions.","triggerScenarios":"mermaid rendered but the SVG it injected had no width/height/viewBox attributes ParseSvgSize understands — a mermaid version that emits a differently-structured SVG, a diagram type that produces zero-size output, or an edge case where the size regex misses.","commonSituations":"Bundled mermaid.js version produces an SVG whose sizing attributes live in a style block or a non-standard attribute; a pie/mindmap diagram that mermaid sizes via CSS only; a mermaid upgrade that changed the SVG shape.","solutions":["Update or clear the cached mermaid.js so a known-good build is used.","Try render=native, which computes size itself and doesn't depend on the injected SVG's attributes.","If reproducible, report the diagram — ParseSvgSize may need to handle the new attribute shape."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// No general pre-check; this is a render-shape corner case. Prefer render=native for diagram types known to size oddly.","typeGuard":null,"tryCatchPattern":"try { png = MermaidImageRenderer.RenderViaChrome(mermaid, bg); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"no measurable svg viewBox\", StringComparison.Ordinal))\n{\n    png = MermaidImageRenderer.RenderNative(mermaid, bg);\n}","preventionTips":["Keep the cached mermaid.js at a version known to emit standard SVG sizing attributes.","For diagram types that size via CSS only, use render=native."],"tags":["mermaid","svg","viewbox","render","chrome"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}