{"record":{"id":"1a809731bef56dd6","repo":"iOfficeAI/OfficeCLI","slug":"headless-browser-produced-no-output","errorCode":null,"errorMessage":"headless browser produced no output.","messagePattern":"headless browser produced no output\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Diagram/MermaidImageRenderer.cs","lineNumber":364,"sourceCode":"    // ----- 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);\n        // a plain source keeps the offline-cached UMD path unchanged.\n        var html = SourceNeedsEsm(mermaid)\n            ? BuildHtmlEsm(mermaid, SourceNeedsElk(mermaid), SafeBackground(background))\n            : BuildHtml(mermaid, ResolveMermaidJsRef(), SafeBackground(background));\n        var htmlPath = Path.Combine(Path.GetTempPath(), $\"ocli_mmd_{Guid.NewGuid():N}.html\");\n        File.WriteAllText(htmlPath, html);\n        try\n        {\n            var dom = HtmlScreenshot.DumpDom(htmlPath)\n                ?? throw new InvalidOperationException(\"headless browser produced no output.\");\n\n            // 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);","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Diagram/MermaidImageRenderer.cs#L346-L382","documentation":"The chrome-family renderer writes an HTML file and asks HtmlScreenshot.DumpDom to load it in a headless browser and return the rendered DOM. DumpDom returned null — the browser produced no output at all. This is the earliest failure point in the two-pass chrome path: the DOM dump (used to read the diagram's viewBox and the MMDREADY/MMDSYNTAX/MMDERR title) never came back.","triggerScenarios":"HtmlScreenshot.DumpDom returns null when the headless browser failed to launch or crashed before emitting any DOM — missing chrome binary, chrome killed on launch (sandbox/permissions), a timeout inside DumpDom itself, or the html path being unreadable.","commonSituations":"Running headless chrome as root without --no-sandbox; chrome not installed or not on the resolver path; a locked-down CI container that blocks process spawning; an OS update removed a chrome dependency library.","solutions":["Verify headless chrome launches: run `chrome --headless --dump-dom file:///tmp/x.html` directly.","If running as root/in a container, ensure the headless launch flags include --no-sandbox (or run as a non-root user).","Confirm chrome is discoverable by the tool's resolver (set the chrome path env var the resolver honors).","Install missing chrome runtime libraries; fall back to render=native if chrome cannot be made to run."],"exampleFix":"// before\nvar dom = HtmlScreenshot.DumpDom(htmlPath)\n    ?? throw new InvalidOperationException(\"headless browser produced no output.\");\n\n// after — distinguish launch failure from empty DOM for a clearer error\nvar dom = HtmlScreenshot.DumpDom(htmlPath);\nif (dom is null)\n    throw new InvalidOperationException(\n        HtmlScreenshot.ChromeAvailable()\n            ? \"headless browser produced no output (chrome launched but returned no DOM).\"\n            : \"headless chrome not found or failed to launch; install chrome or use render=native.\");","handlingStrategy":"validation","validationCode":"// Confirm chrome is launchable before the DOM-dump path\nif (!HtmlScreenshot.ChromeAvailable())\n    throw new InvalidOperationException(\"headless chrome not found; install it or use render=native.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    dom = HtmlScreenshot.DumpDom(htmlPath)\n        ?? throw new InvalidOperationException(\"headless browser produced no output.\");\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"no output\", StringComparison.Ordinal))\n{\n    png = MermaidImageRenderer.RenderNative(mermaid, bg);\n}","preventionTips":["Run chrome with --no-sandbox in root/container contexts.","Keep chrome and its runtime libs installed.","Validate the html temp path is writable."],"tags":["mermaid","chrome","headless","infrastructure","screenshot"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}