tldraw/tldraw · error · MermaidDiagramError

mermaid diagram error: not a mermaid diagram

Error message

mermaid diagram error: not a mermaid diagram

What it means

createMermaidDiagram calls mermaid.parse(text, { suppressErrors: true }). When suppressErrors is true, mermaid.parse returns falsy instead of throwing on invalid syntax. If it returns null/falsy, the function throws MermaidDiagramError('not a mermaid diagram', 'parse'), meaning the input text could not be parsed as any mermaid diagram.

Source

Thrown at packages/mermaid/src/createMermaidDiagram.ts:78

	// a static import, which compiles to require(<esm>) and throws
	// ERR_REQUIRE_ESM on Node <20.19, Jest, and ts-node) and avoids pulling
	// mermaid in when @tldraw/mermaid is merely imported.
	const mermaid = (await import('mermaid')).default

	mermaid.initialize({
		...MERMAID_CONFIG,
		...(options.mermaidConfig ?? {}),
		flowchart: { ...MERMAID_CONFIG.flowchart, ...options.mermaidConfig?.flowchart },
		state: { ...MERMAID_CONFIG.state, ...options.mermaidConfig?.state },
		mindmap: { ...MERMAID_CONFIG.mindmap, ...options.mermaidConfig?.mindmap },
		sequence: { ...MERMAID_CONFIG.sequence, ...options.mermaidConfig?.sequence },
		themeVariables: { ...MERMAID_CONFIG.themeVariables, ...options.mermaidConfig?.themeVariables },
	})

	const parsedResult = await mermaid.parse(text, { suppressErrors: true })

	if (!parsedResult) {
		throw new MermaidDiagramError('not a mermaid diagram', 'parse')
	}

	const offscreen = document.createElement('div')
	offscreen.style.position = 'absolute'
	offscreen.style.left = '-9999px'
	offscreen.style.top = '-9999px'
	offscreen.style.overflow = 'hidden'
	document.body.appendChild(offscreen)

	try {
		const parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg

		// Reuse the live SVG that mermaid.render() already mounted into the
		// offscreen container.  This avoids a second DOM mount and ensures
		// getBBox() works for every diagram type (state diagrams in particular
		// lack explicit dimension attributes and rely on live layout).
		let liveSvg = offscreen.querySelector('svg')

View on GitHub (pinned to b31086b447)

Solutions

  1. Validate the mermaid text with mermaid.parse before calling createMermaidDiagram
  2. Show the user a syntax error and let them fix the diagram text
  3. Wrap the call in try/catch for MermaidDiagramError and present a user-facing error message
Defensive patterns

Strategy: try-catch

Validate before calling

const mermaid = await import('mermaid')
const parsed = await mermaid.parse(text, { suppressErrors: true })
if (!parsed) {
  // show user a syntax error before calling createMermaidDiagram
}

Try / catch

try {
  await createMermaidDiagram(editor, text)
} catch (e) {
  if (e instanceof MermaidDiagramError) {
    // show user-friendly diagram error
  }
}

Prevention

When it happens

Trigger: Passing plain text or arbitrary strings that are not valid mermaid syntax; passing mermaid syntax with a typo in the diagram type keyword; passing an empty string; passing text with a diagram type mermaid does not recognize at parse time.

Common situations: User-generated diagram text in a text box that has not been validated; pasting content that lost its mermaid code fence; incomplete diagram definitions (e.g. 'graph' with no edges or nodes).

Related errors


AI-assisted analysis of tldraw/tldraw@b31086b447 (2026-08-12). Data as JSON: /api/errors/c4569d9a3d890842. Report an issue: GitHub.