# Understanding Mermaid Diagram Validation Logic in CodeWiki: A Technical Deep Dive

> Explore the mermaid diagram validation logic in CodeWiki. Discover how the handle_mermaid_validation function sanitizes diagrams through five key transformations. Learn more now.

- Repository: [Luong Quang Dung/codewiki](https://github.com/quangdungluong/codewiki)
- Tags: deep-dive
- Published: 2026-02-16

---

**The mermaid diagram validation logic in CodeWiki sanitizes raw LLM-generated diagrams through the `handle_mermaid_validation` function in [`api/generate_diagram.py`](https://github.com/quangdungluong/codewiki/blob/main/api/generate_diagram.py), applying five specific transformations to fix JSON formatting, arrow syntax, percent signs, escaped quotes, and deprecated direction keywords before frontend rendering.**

CodeWiki relies on large language models to generate Mermaid diagrams, but raw LLM output often contains syntax errors that break rendering. The **mermaid diagram validation logic** implemented in the CodeWiki repository ensures that malformed diagrams are automatically corrected before they reach the React frontend. This validation pipeline lives in the API layer and performs surgical text transformations to enforce Mermaid syntax compliance.

## Where Mermaid Diagram Validation Logic Lives in CodeWiki

The core validation function resides in [`api/generate_diagram.py`](https://github.com/quangdungluong/codewiki/blob/main/api/generate_diagram.py) at approximately lines 52-75. This function operates as the final sanitization step in the diagram generation pipeline, receiving processed output from `process_click_events` immediately before the data streams to the frontend.

```python
processed_diagram = process_click_events(... )
processed_diagram = handle_mermaid_validation(processed_diagram)

```

The `handle_mermaid_validation` function returns a cleaned string that the React component [`frontend/components/Mermaid.tsx`](https://github.com/quangdungluong/codewiki/blob/main/frontend/components/Mermaid.tsx) consumes directly. Additional supporting files include [`frontend/hooks/useDiagram.ts`](https://github.com/quangdungluong/codewiki/blob/main/frontend/hooks/useDiagram.ts), which manages the streaming response, and [`api/services/gemini_service.py`](https://github.com/quangdungluong/codewiki/blob/main/api/services/gemini_service.py), which supplies the raw LLM-generated content that requires validation.

## The Five-Step Mermaid Diagram Validation Process

The validation logic executes five distinct transformation passes to repair common LLM-generated syntax errors. Each step targets a specific Mermaid parsing failure mode.

### 1. JSON Structure Normalization

Raw diagrams may arrive as JSON objects or JSON-encoded strings rather than plain text. The validation logic detects JSON formatting by checking for opening braces and recursively parses the structure to extract the actual diagram content.

```python
if diagram.startswith('{'):
    diagram = json.loads(diagram)
    diagram = list(diagram.values())[0]
try:
    diagram = json.loads(diagram)
except json.JSONDecodeError:
    pass

```

### 2. Arrow Syntax Correction

LLMs frequently generate non-standard arrow operators that Mermaid cannot parse. The validation logic replaces these malformed arrows with valid syntax using chained string replacements.

```python
diagram = (
    diagram.replace('<--', '-->')
           .replace('-->>', '-->')
           .replace('--.', '-->|')
           .replace('.->', '|')
)

```

This correction handles four specific error patterns: bidirectional arrows (`<--`), double-headed arrows (`-->>`), dotted line attempts (`--.` and `.->`).

### 3. Percent-Sign Escaping for Comments

Mermaid requires double percent signs (`%%`) to denote comments at the start of lines. Single percent signs cause parsing failures. The validation logic uses a regular expression to detect and escape lone percent signs at line beginnings.

```python
diagram = re.sub(r'(^\\s*)%(?!%)', r'\\1%%', diagram, flags=re.MULTILINE)

```

This regex ensures that existing double-percent comments remain unchanged while single-percent markers are properly escaped.

### 4. Quoted Node Label Sanitization

Node labels containing escaped quotes often arrive with malformed backslash sequences that break Mermaid's bracket syntax. The validation logic cleans these escape characters using regex substitution to ensure valid identifier strings.

```python
diagram = re.sub(r'\\[\\s*\"([^\\\"]*?)\\\\\\\"([^\\\"]*?)\"\\s*\\]', r'['\"\\1'\\2\"]', diagram)

```

This transformation removes stray escape sequences while preserving the actual label content within the node brackets.

### 5. Deprecated Direction Keyword Removal

The `direction TD` directive is deprecated in certain Mermaid contexts and can interfere with custom layout logic. The validation logic strips this keyword entirely to prevent rendering conflicts.

```python
diagram = re.sub(r'direction TD', '', diagram)

```

This ensures compatibility with the React frontend's diagram rendering implementation.

## Complete Code Example: Validating a Malformed Diagram

The following example demonstrates how `handle_mermaid_validation` transforms a severely malformed LLM output into valid Mermaid syntax.

**Input (raw LLM output with multiple errors):**

```python
raw_diagram = '''
{
  "diagram": "graph TD\\n% Invalid comment\\nA <-- B\\nC -->> D\\nE --. F\\nG .-> H\\ndirection TD\\n[\\\\"Node \\\\\\"1\\\\\"\\\\"] --> [\\\\"Node \\\\\\"2\\\\\"\\\\"]"
}
'''

```

**Validation execution:**

```python
import json
import re

def handle_mermaid_validation(diagram):
    # Step 1: JSON handling

    if diagram.startswith('{'):
        diagram = json.loads(diagram)
        diagram = list(diagram.values())[0]
    try:
        diagram = json.loads(diagram)
    except json.JSONDecodeError:
        pass
    
    # Step 2: Arrow syntax

    diagram = (
        diagram.replace('<--', '-->')
               .replace('-->>', '-->')
               .replace('--.', '-->|')
               .replace('.->', '|')
    )
    
    # Step 3: Percent escaping

    diagram = re.sub(r'(^\\s*)%(?!%)', r'\\1%%', diagram, flags=re.MULTILINE)
    
    # Step 4: Quoted labels

    diagram = re.sub(r'\\[\\s*\"([^\\\"]*?)\\\\\\\"([^\\\"]*?)\"\\s*\\]', r'['\"\\1'\\2\"]', diagram)
    
    # Step 5: Direction removal

    diagram = re.sub(r'direction TD', '', diagram)
    
    return diagram

# Process the raw diagram

clean_diagram = handle_mermaid_validation(raw_diagram)
print(clean_diagram)

```

**Output (validated Mermaid):**

```mermaid
graph TD
%% Invalid comment
A --> B
C --> D
E -->|> F
G | H
["Node '1'"] --> ["Node '2'"]

```

## Integration with the CodeWiki Frontend

The validation logic operates as a middleware layer between the LLM service and the React frontend. After `handle_mermaid_validation` completes its transformations, the sanitized string flows through the following components:

- **[`frontend/components/Mermaid.tsx`](https://github.com/quangdungluong/codewiki/blob/main/frontend/components/Mermaid.tsx)**: Receives the validated diagram string and renders it using the Mermaid.js library. This component expects strictly valid syntax, as any remaining errors would cause client-side rendering failures.

- **[`frontend/hooks/useDiagram.ts`](https://github.com/quangdungluong/codewiki/blob/main/frontend/hooks/useDiagram.ts)**: Manages the streaming response from the API, ensuring that the validated diagram arrives intact at the UI layer. This hook handles the asynchronous data flow between the generation endpoint and the Mermaid component.

- **[`api/services/gemini_service.py`](https://github.com/quangdungluong/codewiki/blob/main/api/services/gemini_service.py)**: Supplies the raw, unvalidated diagram content generated by Google's Gemini LLM. This raw output frequently contains the syntax errors that `handle_mermaid_validation` corrects.

This architecture ensures that users never encounter broken diagram renders, even when the underlying LLM produces malformed Mermaid syntax.

## Summary

The **mermaid diagram validation logic** in CodeWiki provides a robust sanitization pipeline that bridges the gap between unpredictable LLM output and strict Mermaid.js syntax requirements. Key takeaways include:

- The **`handle_mermaid_validation`** function in [`api/generate_diagram.py`](https://github.com/quangdungluong/codewiki/blob/main/api/generate_diagram.py) serves as the central validation engine, processing diagrams immediately after click-event injection.
- Five specific transformations address common LLM errors: **JSON extraction**, **arrow syntax correction**, **percent-sign escaping**, **quoted label sanitization**, and **deprecated keyword removal**.
- The validation operates as middleware between **[`api/services/gemini_service.py`](https://github.com/quangdungluong/codewiki/blob/main/api/services/gemini_service.py)** (LLM provider) and **[`frontend/components/Mermaid.tsx`](https://github.com/quangdungluong/codewiki/blob/main/frontend/components/Mermaid.tsx)** (rendering layer), ensuring client-side stability.
- Regular expressions and string replacements handle edge cases that would otherwise cause Mermaid.js parsing failures, such as lone percent signs or malformed bidirectional arrows.

## Frequently Asked Questions

### How does CodeWiki handle JSON-wrapped Mermaid diagrams?

CodeWiki's validation logic detects JSON-formatted diagrams by checking for opening braces at the start of the string. The **`handle_mermaid_validation`** function parses the JSON structure, extracts the diagram value using `list(diagram.values())[0]`, and attempts secondary JSON decoding to handle double-encoded strings. This ensures that diagrams arriving as API response objects are flattened into valid Mermaid source strings before syntax correction begins.

### What specific arrow syntax errors does the validation logic correct?

The validation routine corrects four common malformed arrow patterns generated by LLMs: bidirectional arrows (`<--` converted to `-->`), double-headed arrows (`-->>` converted to `-->`), incorrect dotted line syntax (`--.` converted to `-->|`), and malformed dot arrows (`.->` converted to `|`). These replacements occur through chained string operations in `handle_mermaid_validation` to ensure compatibility with Mermaid.js parser requirements.

### Why does CodeWiki strip the `direction TD` keyword from diagrams?

The validation logic removes the `direction TD` directive using regex substitution because this keyword is deprecated in certain Mermaid contexts and interferes with CodeWiki's custom layout logic implemented in the React frontend. The `re.sub(r'direction TD', '', diagram)` operation prevents rendering conflicts in [`frontend/components/Mermaid.tsx`](https://github.com/quangdungluong/codewiki/blob/main/frontend/components/Mermaid.tsx) while maintaining the diagram's structural integrity through the default top-down behavior.

### How does the percent-sign escaping prevent Mermaid parsing errors?

Mermaid.js requires double percent signs (`%%`) to denote comments at the beginning of lines; single percent signs cause parser failures. The validation logic uses the regex pattern `r'(^\\s*)%(?!%)'` with `re.MULTILINE` flags to detect single percent signs at line starts that aren't already doubled, replacing them with `%%` through the substitution `r'\\1%%'`. This ensures comment syntax compliance without altering legitimate double-percent markers.