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

The mermaid diagram validation logic in CodeWiki sanitizes raw LLM-generated diagrams through the handle_mermaid_validation function in 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 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.

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 consumes directly. Additional supporting files include frontend/hooks/useDiagram.ts, which manages the streaming response, and 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.

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.

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.

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.

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.

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):

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:

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):

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: 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: 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: 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 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 (LLM provider) and 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →