Skip to content

fix(serve): mermaid fenced blocks broken by HTML-entity escaping#273

Merged
avrabe merged 2 commits into
mainfrom
fix/mermaid-fenced-block-escaping
May 12, 2026
Merged

fix(serve): mermaid fenced blocks broken by HTML-entity escaping#273
avrabe merged 2 commits into
mainfrom
fix/mermaid-fenced-block-escaping

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 12, 2026

Summary

User-reported bug (v0.6.0 + v0.8.0): a \``mermaidfenced block inside a YAML artifact description renders-->as-->in the dashboard's

`, so mermaid.js fails with "Syntax error in text" and the diagram never appears.

Root cause: render_markdown (rivet-core/src/markdown.rs) injects synthetic <pre class="mermaid"> wrappers but still passes the fenced body to pulldown-cmark's html::push_html, which HTML-entity-escapes Event::Text — so -->--&gt;, <|--&lt;|--, etc. Mermaid diagram syntax is full of </>/&, so this breaks essentially every diagram type.

Fix: re-tag the in-mermaid Event::Text segments as Event::Html so they pass through push_html verbatim. Diagram source contains no HTML tags; a </pre> smuggled into a \``mermaidblock would at worst close the block early, and<script>etc. are still stripped by the existingsanitize_html pass. (document.rs's separate document renderer already emits the body verbatim — only render_markdown` had the bug.)

Verified locally: rivet serve/artifacts/ARCH-CORE-001 now contains Config --> Store verbatim, zero --&gt;.

Test coverage

  • markdown.rs unit tests (×2): stateDiagram [*] --> arrows survive verbatim with no --&gt;; classDiagram <|-- survives with no &lt;|--.
  • tests/playwright/mermaid.spec.ts (new): raw HTML of /artifacts/ARCH-CORE-001 has Config --> Store verbatim and no --&gt;; mermaid.js renders it to an <svg> with no "Syntax error" box.

Follow-up (not in this PR)

The fix is diagram-type-agnostic (it just stops escaping the body), so it covers flowchart/state/class/sequence/ER/gantt/etc. at once. A broader Playwright matrix that exercises one fixture artifact per diagram type would be nice belt-and-suspenders but is its own task — flagging per the request to "test all kinds of mermaid graphics".

Test plan

  • cargo test -p rivet-core markdown green (incl. 2 new tests)
  • Playwright mermaid.spec.ts green in the E2E job
  • No regression in existing markdown / mermaid tests

🤖 Generated with Claude Code

`render_markdown` injected synthetic `<pre class="mermaid">` wrappers but
still let the fenced body flow through pulldown-cmark's `html::push_html`,
which HTML-entity-escapes Event::Text — so mermaid's core `-->` arrow
rendered as `--&gt;` (and class-diagram `<|--` as `&lt;|--`), and
mermaid.js rejected the diagram with "Syntax error in text". Reported by
a user against v0.6.0 and v0.8.0.

Re-tag the in-mermaid Text segments as Event::Html so they pass through
unescaped. Mermaid diagram source contains no HTML tags; a `</pre>`
smuggled into a ```mermaid block would at worst close the block early,
and `<script>` etc. are still stripped by the `sanitize_html` pass.
(`document.rs`'s separate document renderer already emits the body
verbatim via `join("\n")` — only `render_markdown` had the bug.)

Coverage:
- two markdown.rs unit tests: stateDiagram `[*] -->` arrows survive
  verbatim with no `--&gt;`; classDiagram `<|--` survives with no `&lt;|--`.
- new tests/playwright/mermaid.spec.ts: ARCH-CORE-001's embedded
  ```mermaid flowchart serves with `Config --> Store` verbatim, and
  mermaid.js renders it to an SVG with no "Syntax error" box.

Fixes REQ-032.

Implements: REQ-032
Verifies: REQ-032

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

📐 Rivet artifact delta

No artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph.

Wraps an over-long assert!() the formatter flagged. No behaviour change.

Trace: skip

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 90bb1a1 Previous: 02b9328 Ratio
validate/10000 20318603 ns/iter (± 1714130) 16904098 ns/iter (± 1013276) 1.20
query/10000 138521 ns/iter (± 410) 91811 ns/iter (± 267) 1.51

This comment was automatically generated by workflow using github-action-benchmark.

@avrabe avrabe merged commit ff89f98 into main May 12, 2026
23 of 38 checks passed
@avrabe avrabe deleted the fix/mermaid-fenced-block-escaping branch May 12, 2026 18:54
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant