Repository navigation
Description
Describe the bug
None of the three mermaid diagrams on the published site render. They are not blank or broken images — they are absent from the HTML entirely.
This is a different cause from #6020, which was the client-side renderer being blocked by the ASF Content-Security-Policy. #6021 fixed that by switching to build-time SVG (mermaid_output_format = 'svg'), and in doing so replaced one silent failure with another.
Steps to reproduce
Fetch the deployed pages from the asf-site branch and look for any diagram:
$ gh api "repos/apache/datafusion-comet/contents/contributor-guide/memory_management.html?ref=asf-site" \
--jq .content | base64 -d | grep -c 'svg\|mermaid\|<object'
0
$ gh api "repos/apache/datafusion-comet/contents/contributor-guide/ci.html?ref=asf-site" \
--jq .content | base64 -d | grep -c 'svg\|mermaid\|<object'
0
$ gh api "repos/apache/datafusion-comet/git/trees/asf-site?recursive=1" \
--jq '[.tree[].path | select(test("mermaid"))] | length'
0
On contributor-guide/memory_management.html the text runs straight from
…who ends up charged for the bytes:</p> into the next <section> heading.
The hand-authored SVGs (shim_pattern.svg, query_context_journey.svg, error_pipeline_overview.svg) are all present, so this is specific to the mermaid pipeline.
Expected behavior
The two diagrams in docs/source/contributor-guide/memory_management.md and the one in docs/source/contributor-guide/ci.md render on the published pages.
Additional context
What is happening. sphinxcontrib-mermaid downgrades a render failure to a Sphinx warning and drops the node. The build stays green, the deploy runs, and the pages publish with a diagram-shaped hole. docs/README.md and the comment on the Install mermaid-cli step in .github/workflows/docs.yaml both already warn that this is the failure mode; nothing enforces it.
The publish commit for #6021 (b9ea47c16) shows it exactly: it removed the <pre class="mermaid"> blocks and the jsdelivr script import from both pages and added nothing in their place — no <object>, and no _images/mermaid-*.svg anywhere in the tree.
So mmdc is not producing output in the docs job, even though the job is green and Install mermaid-cli succeeds (21s in the run for d1bf687eb).
Why it was not caught. #6021 was verified locally on macOS, where it produced 2 and 1 <object> embeds on those two pages. The docs job only runs on push to main (ci.yml, docs is push-tier by POLICY), so no docs build ran on the pull request, and once on main the failure is silent by construction.
Likely cause. mmdc drives headless Chrome through puppeteer. Ubuntu restricts unprivileged user namespaces by AppArmor policy from 23.10 onwards, so Chrome's setuid sandbox cannot start on an ubuntu-24.04 runner and mmdc exits non-zero — the canonical "renders locally, dies in CI" shape for mermaid-cli. The alternative is puppeteer's Chrome not being where mmdc looks after a global install. Either way sphinxcontrib-mermaid swallows it, and the job log is the only place the difference shows.
Proposed fix
- Pass
mmdca puppeteer config with--no-sandbox(the CI container is already the isolation boundary). - Make the failure loud: render every
```mermaidfence in preflight so it fails on the pull request, and assert after the build that every fence produced a non-empty SVG that some page references, before the publish step runs.
Component(s)
Documentation
Activity
andygrove commentedon Sep 20, 2026
Refining the "likely cause" above, because a local reproduction turned up a second candidate that is at least as likely, and a third layer of swallowing.
@mermaid-js/mermaid-clideclarespuppeteeras a peer dependency and shipspuppeteer-core, so the browsermmdcdrives comes from puppeteer'spostinstall. That script is:It catches its own failure and exits 0. So a flaky or blocked browser fetch during
npm install -g @mermaid-js/[email protected]leaves a green install step with no browser, andmmdcthen dies at launch:which
sphinxcontrib-mermaidturns into a warning and a dropped diagram. Three layers, each one silent.That is the exact error the reproduction produced. It does not prove it is what happened on the runner — the browser fetch is blocked in my environment, so I cannot separate it from the AppArmor sandbox theory, and the job log for the docs run is not reachable from here. But it does mean there are two plausible causes rather than one, and both are cheap to close out:
puppeteer browsers install chrome-headless-shellafter the npm install, where a failure is allowed to fail the job, removes the silent-no-browser case--no-sandboxpuppeteer config removes the AppArmor caseWhichever one it was, the render check reports the actual
mmdcstderr, so the next docs run says so outright instead of publishing a hole.