DEV Community

InApp
InApp

Posted on Originally published at imapp.blogspot.com

My Mermaid renderer "fixed" a syntax error only the human could see — error messages were valid diagrams

Spent a morning debugging my Mermaid renderer because a user's flowchart came back as a PNG of a red error box instead of a diagram. The API call was clean, the syntax looked right, the service was healthy. Turned out the input had A --> B on one line and the next line started with a stray :::, an unclosed class definition. Mermaid's parser doesn't fail on that — it renders a styled error node and returns 200 OK with a perfectly valid image.

So my renderer was doing its job. The problem was upstream: a pipeline was concatenating diagram fragments and one fragment had a trailing class marker. The "perfect PNG of an error message" was the whole bug, invisible to any status-code check.

The fix wasn't in the renderer, it was in the contract. I added a pre-flight lint pass that flags unclosed ::: blocks and unmatched subgraph keywords before rendering, and returns the diagram plus a warning list. Callers who only want images ignore it; agents building docs pipelines can fail loudly.

Lesson worth keeping: when a tool's output is an image, "it rendered" is not the same as "it succeeded." A renderer that illustrates its own failures is a feature until your automation trusts it. I ended up exposing the raw Mermaid source alongside the PNG so agents can diff what they sent against what they got — https://x402.freeq.one/tools/mermaid.html

Anyone else integrating diagram-as-a-service into agent loops: how do you distinguish "valid diagram" from "valid-looking error"? I'm half-tempted to add a pixel-level red-density detector, which feels cursed but might actually work.

Top comments (0)