Learn (Almost) Anything
CatalogDownload course

Diagrams as Code with Mermaid

Start with the flowchart since its node-and-edge model underpins everything else: directions (TD/LR), node shapes, edge types, labels, and subgraphs. Crucially, you'll learn to decode the 'Syntax error in graph' messages — the usual culprits are stray characters in labels, reserved words like 'end', unquoted text, and bad indentation. By the end you can sketch a flowchart in a doc and fix it when it won't render.

enMini-course6 lessons1 module5
Diagrams as Code with MermaidMermaid Diagrams in Practicemermaiddiagramscodepractice

Flowcharts and Reading Mermaid Errors

Start with the flowchart since its node-and-edge model underpins everything else: directions (TD/LR), node shapes, edge types, labels, and subgraphs. Crucially, you'll learn to decode the 'Syntax error in graph' messages — the usual culprits are stray characters in labels, reserved words like 'end', unquoted text, and bad indentation. By the end you can sketch a flowchart in a doc and fix it when it won't render.

Why Start with Flowcharts

The flowchart is Mermaid's foundation. Its node-and-edge model — named things connected by arrows — reappears in every other diagram type in this course. Once you can write one from scratch and debug it when the renderer goes quiet, everything else slots in quickly.

Your First Flowchart

flowchart TD
    A[Start] --> B{Is user logged in?}
    B -- Yes --> C[Show dashboard]
    B -- No --> D[Redirect to login]
    D --> E([Login page])
    E --> B

Reading it line by line:

  • flowchart TD — diagram type plus direction (Top-Down). graph TD is the older alias; they're interchangeable.
  • A[Start] — node with ID A, rectangular shape, label "Start"
  • --> — directed arrow
  • {...} — diamond (decision)
  • -- Yes --> — arrow with an inline label
  • ([...]) — stadium/pill shape, commonly used for start/end terminals

Node IDs (A, B, C) are internal handles the parser uses. The text inside the brackets is what renders on screen. Keep IDs short and alphanumeric — that avoids most errors before you even start.

Node Shapes: The Core Four

Four shapes cover the vast majority of real diagrams:

SyntaxShapeTypical use
A[Label]RectangleProcess step, action
A(Label)Rounded rectSofter process step
A{Label}DiamondDecision / branch
A((Label))CircleJunction, start/end

A few more worth knowing:

SyntaxShapeTypical use
A([Label])Stadium / pillEvent, terminator
A[(Label)]CylinderDatabase
A{{Label}}HexagonPreparation / config
A>Label]AsymmetricFlag, interrupt
InteractiveNode Syntax → Shape#int-1
Match each Mermaid node syntax to the shape it produces. Tap one item from each column to pair them.
Quick recall #rc-1

In a Mermaid flowchart, which node shape represents a decision point?

Show answer

Diamond (syntax: {Label})

Edge Types

flowchart LR
    A --> B        %% Arrow (default)
    C --- D        %% Open link, no arrowhead
    E -.-> F       %% Dotted arrow
    G ==> H        %% Thick arrow
    I --o J        %% Circle end
    K --x L        %% Cross / rejection
    M <--> N       %% Bidirectional
    O ~~~ P        %% Invisible link (layout nudge)

Labels sit between the dashes or in pipes — both are valid:

A -- approved --> B
A -->|rejected| C

The pipe form is more common in older snippets; the -- text --> form reads more naturally in long chains. Pick one style per diagram and stick to it.

Check yourself #cp-1

Without scrolling back up: what does A --x B render — and when would you reach for A ~~~ B (three tildes)?

Show answer

--x renders an arrow with a cross at the receiving end, used to signal rejection or a stopped flow. ~~~ is an invisible link — no visible edge or arrowhead — used purely to nudge the layout engine and push nodes apart without implying a logical connection between them.

Quick recall #rc-3

How do you add a label to an edge in a Mermaid flowchart?

Show answer

Use A -- label --> B or A -->|label| B; both forms are equivalent

Direction

The second word after flowchart controls the layout:

  • TD / TB — top to bottom (approval chains, deep hierarchies)
  • LR — left to right (pipelines, timelines, CI flows)
  • BT — bottom to top (less common)
  • RL — right to left (rarest)

One-word change, dramatic layout difference. When a TD diagram gets too tall and cramped, try LR — it often resolves readability instantly.

Subgraphs

Subgraphs draw a labeled box around a group of nodes:

flowchart TD
    subgraph auth["Auth service"]
        direction LR
        Login --> TokenCheck --> JWT
    end
    subgraph api["API layer"]
        Request --> Validate --> Handler
    end
    JWT --> Request

Rules to remember:

  • subgraph id["title"] opens; end closes
  • A direction inside a subgraph is independent of the outer diagram's direction
  • Edges can cross subgraph boundaries freely (JWT --> Request does this above)
Check yourself #cp-2

What single keyword closes a subgraph — and why is that the most common cause of 'Syntax error in graph' messages for people writing flowcharts?

Show answer

The keyword end closes a subgraph. Because the parser watches for end everywhere in the source, using it as a plain node ID (e.g. A --> end) is misread as an attempt to close a subgraph that was never opened, which throws a syntax error. Rename the node to stop, finish, or capitalize to END.

---

Reading Mermaid Errors

Mermaid's error report is famously unhelpful: *"Syntax error in graph"*, no line number. The good news is that four culprits account for the vast majority of broken diagrams.

1. The word end

end is a reserved keyword that closes subgraphs. The parser rejects it as a node ID:

%% BROKEN
flowchart TD
    A[Start] --> end

Fix: capitalize or rename.

%% FIXED
flowchart TD
    A[Start] --> stop

Need the word "end" as visible label text? Quote it: A --> z["end of process"] — quotes let reserved words appear on screen without confusing the parser.

2. Unquoted special characters in labels

Parentheses, slashes, curly braces, and colons inside labels confuse the parser because those characters have meaning in node syntax. Wrap the whole label in double quotes:

%% BROKEN
flowchart LR
    A[GET /api/users (v2)] --> B[200 OK]

%% FIXED
flowchart LR
    A["GET /api/users (v2)"] --> B["200 OK"]

Inside quoted labels, <br/> gives a line break, and HTML entities (&lt;, &gt;, &amp;) work fine.

3. Node IDs starting with o or x

Mermaid uses o and x as edge-end modifiers (--o, --x). A node ID beginning with one of those letters, in certain positions in a connection, can be misread as part of an edge token:

%% RISKY — 'order' and 'output' both start with 'o'
flowchart TD
    order --> output

Fix: rename to something unambiguous — ord, out, orderNode. This one trips people up constantly because the diagram *sometimes* works and *sometimes* doesn't, depending on Mermaid version.

4. Mismatched brackets

Every shape has its specific bracket pair. Mixing them is a quiet error the parser won't forgive:

%% BROKEN
A{Is valid?] --> B[OK]

%% FIXED
A{Is valid?} --> B[OK]

The only intentionally asymmetric shape is A>Label]. Every other shape uses matching pairs — double-check these when the error seems inexplicable.

The Debugging Loop

When a diagram won't render:

1. Paste into Mermaid Live — the error panel highlights the problematic token and gives you a live preview as you type

2. Scan for end as a node ID or bare label

3. Look for unquoted special characters in labels

4. Check IDs starting with o or x

5. Count brackets: every [ needs ], every { needs }, every (( needs ))

InteractiveSpot the Bug#int-2
  1. Why does `A[Start] --> end` break a flowchart diagram?
  2. What breaks `A[GET /api/v1 (users)] --> B`?
  3. A diagram containing `order --> output` renders incorrectly in some Mermaid versions. The most likely reason is:
Each question shows a broken Mermaid snippet. Pick the real reason it fails.

---

Quick recall #rc-2

Using end as a node ID in a Mermaid flowchart causes an error because ___

Show answer

it's a reserved keyword that closes subgraphs

Worked Example: An API Order Flow

Here's a realistic diagram using subgraphs, a decision node, labeled edges, and a database cylinder. Every choice has a reason:

flowchart TD Client(["Client"]) subgraph backend["Backend"] direction TD Auth{"Auth check"} Handler["Request handler"] DB[("Orders DB")] end Client -->|order request| Auth Auth -- valid --> Handler Auth -- invalid --> Err["401 Unauthorized"] Handler --> DB DB -->|row data| Handler Handler -->|200 OK| Client
flowchart TD
    Client(["Client"])

    subgraph backend["Backend"]
        direction TD
        Auth{"Auth check"}
        Handler["Request handler"]
        DB[("Orders DB")]
    end

    Client -->|order request| Auth
    Auth -- valid --> Handler
    Auth -- invalid --> Err["401 Unauthorized"]
    Handler --> DB
    DB -->|row data| Handler
    Handler -->|200 OK| Client
A complete API order flow: subgraph grouping, a decision diamond, a database cylinder, and labeled edges.
  • Err instead of error — avoids reserved-word collisions in some Mermaid versions
  • DB[("Orders DB")] — cylinder shape with a quoted label (space inside)
  • Err["401 Unauthorized"] — space and digits inside the label, so it's quoted
  • Subgraph direction TD declared explicitly — good habit even when it matches the outer diagram, so future additions inside the subgraph behave predictably
  • Simple text labels on arrows (valid, invalid, row data) — no quoting needed when there are no special characters

Your turn: sketch any process you know — a CI pipeline, a login flow, a form submission — as a flowchart TD. Add at least one {decision}, one subgraph, and one dotted -.-> edge. Paste it into Mermaid Live and work through any errors that come up before moving on.

The node-and-edge vocabulary you've built here carries directly into every diagram type ahead. Sequence diagrams are next — same instinct, different notation.

Self-check

  1. You're drawing a checkout process with three stages: customer review, payment decision, then confirmation. Which combination of node shapes best represents these steps?
  2. You write `A[Start] --> end` but get 'Syntax error in graph' with no line number. What's wrong?
  3. Your diagram contains these lines but won't render: ``` A[Check user] B[Display (profile)] A --> B ``` What's the correct fix?
  4. Your diagram uses node IDs `order` and `output`, but you get 'Syntax error in graph' intermittently even though the IDs look valid. What's happening?
  5. Your `flowchart TD` diagram is too tall and cramped. You try switching to `flowchart LR` and the readability improves dramatically. Why does this simple change help so much?
  6. Inside a subgraph, you declare `direction LR` while the outer diagram is `flowchart TD`. What happens to edges within that subgraph?
  7. You want the text 'end of process' to appear as a node label in your diagram. Why won't `A --> end` work, and what's the fix?
  8. What's the key difference between `A --- B` and `A --> B`?
  9. You're showing that user feedback loops back to the design phase. Which edge type best captures this two-way flow?
  10. You're documenting a step that retrieves data from a database. Which node shape is most appropriate?
  11. Your diagram gives 'Syntax error in graph' with no line number. What's the most effective first debugging step?
  12. You write `A{Is valid?] --> B`. What's the syntax error here?
  13. The article emphasizes that flowcharts are Mermaid's foundation because the 'node-and-edge model reappears in every other diagram type.' What does this tell you about learning the course?
  14. The article shows subgraphs can have their own `direction` independent of the outer diagram. Why might you declare `direction RL` in a subgraph even if the outer diagram is `flowchart TD`?
  15. The article states that node IDs like `A` and `B` are 'internal handles the parser uses,' while labels like 'Start' and 'Check status' are 'what renders on screen.' Why does this distinction matter?
  16. You write `A[Check status (24h)] --> B` but get a syntax error because parentheses are special characters. What's the correct fix?

Homework

Fix Four Common Mermaid Errorstext

Below are four short flowchart snippets, each with one syntax error from the article: (1) reserved word 'end', (2) unquoted special characters, (3) node ID starting with 'o' or 'x', or (4) mismatched brackets. Snippet 1: flowchart TD A[Start] --> end Snippet 2: flowchart LR A[GET /api/users (v2)] --> B[200 OK] Snippet 3: flowchart TD order --> A[Next] A --> output[Final] Snippet 4: flowchart TD A{Is valid?] --> B[OK] For each snippet, identify which error type it contains, then submit the corrected code. Label your fixes as 'Fixed 1:', 'Fixed 2:', etc., and paste each into Mermaid Live to verify it renders without errors.

1. All four error types are correctly identified. 2. Each corrected snippet renders in Mermaid Live without syntax errors. 3. Fixes are minimal—only the error is changed, the logic is preserved. 4. Node IDs and visible labels make sense for the flow.

Design a Checkout Flow with Subgraphs and Decisionsimage

Design a flowchart for an e-commerce checkout process. Your diagram must include: - An authentication check (decision node with ≥2 branches) - Inventory validation (another decision node) - A payment processing subgraph containing ≥2 nodes - At least two labeled edges with meaningful text (e.g., 'approved', 'out of stock') Choose TD (top-down) or LR (left-right) direction based on what looks clearest. Use standard node shapes: [rectangles] for steps, {diamonds} for decisions. Quote any labels containing special characters (/, colons, parentheses, etc.). Build your diagram, test it in Mermaid Live to confirm no syntax errors, then submit a screenshot of the complete rendered diagram.

1. Diagram is syntactically valid and renders in Mermaid Live without errors. 2. Contains ≥2 decision nodes with appropriate edge labels (e.g., 'yes'/'no', 'approved'/'rejected'). 3. Contains 1 subgraph labeled for payments, with ≥2 nodes inside. 4. Flow logically traces a checkout: authentication → validation → payment → outcome. 5. Node shapes match their purpose (diamonds for branches, rectangles for actions). 6. Labels containing special characters are quoted; node IDs are concise and alphanumeric.

Debug and Extend a CI/CD Pipelinetext

Below is a partial, buggy flowchart of a CI/CD pipeline: flowchart TD subgraph ci["CI Pipeline"] A[Checkout code] --> B[Run tests] B --> C{Tests pass?} end C -- Yes --> D[Build image] C -- No --> E[Notify team] E --> end D --> F[Deploy to staging] Tasks: 1. Identify and fix the one syntax error. 2. Add exactly 3 new nodes to extend the flow past deployment (e.g., run health checks, smoke tests, archive logs, send success notification—pick any 3 that make sense). 3. Add 2-3 edges to connect your new nodes and complete the workflow. 4. Ensure all labels are clear and quote them if they contain special characters. Submit the corrected and extended code.

1. Syntax error is correctly fixed; the complete code renders in Mermaid Live. 2. Exactly 3 new nodes are added after 'Deploy to staging'. 3. New nodes use appropriate shapes (rectangles for checks or notifications, diamonds only if a new decision is needed). 4. 2-3 new edges logically connect the extensions and form a coherent workflow. 5. All labels are clear, relevant to CI/CD, and quoted if they contain special characters. 6. Final flow reads logically: checkout → test → build → deploy → validation/notification.

Submit and get assignments reviewed in the Learn (Almost) Anything app.

Sources

  1. Flowchart Syntax | Mermaid
  2. Flowchart / Graph node containing keywords causes syntax error · mermaid-js/mermaid · GitHub