danny-avila/LibreChat · error · Error

Failed to load mermaid library

Error message

Failed to load mermaid library

What it means

Thrown by the Mermaid render hook when `loadMermaid()` resolves to a falsy value. `loadMermaid` returns `null` in two situations: during SSR (`typeof window === 'undefined'`), or when the dynamic `import('mermaid')` rejects. Note that `loadMermaid` caches its promise in a module-level variable — if the import fails once, every subsequent call reuses the same rejected promise until a full page reload resets the module.

Source

Thrown at client/src/hooks/Mermaid/useMermaid.ts:116

      securityLevel: 'strict',
      maxTextSize: config?.maxTextSize ?? 50000,
      maxEdges: config?.maxEdges ?? 500,
    };
  }, [customTheme, isDarkMode, config]);

  // Fetch/render function
  const fetchSvg = async (): Promise<string> => {
    // SSR guard
    if (typeof window === 'undefined') {
      return '';
    }

    try {
      // Load mermaid library (cached after first load)
      const mermaidInstance = await loadMermaid();

      if (!mermaidInstance) {
        throw new Error('Failed to load mermaid library');
      }

      // Validate syntax first and capture detailed error
      try {
        await mermaidInstance.parse(content);
      } catch (parseError) {
        // Extract meaningful error message from mermaid's parse error
        let errorMessage = 'Invalid mermaid syntax';
        if (parseError instanceof Error) {
          errorMessage = parseError.message;
        } else if (typeof parseError === 'string') {
          errorMessage = parseError;
        }

        throw new Error(errorMessage);
      }

      // Initialize with config

View on GitHub (pinned to 5ff282f900)

Solutions

  1. If SSR: skip rendering on the server (the hook already returns `''` when window is undefined — ensure the component doesn't call `fetchSvg` during SSR).
  2. If the chunk fails to load at runtime: hard-reload the page to clear the cached rejected promise and fetch the current chunk.
  3. Ensure `mermaid` is a real dependency (not optional/peer) and the bundler emits its chunk; check the Network tab for a failed chunk request.
  4. Relax CSP `script-src`/`connect-src` to allow the bundled chunk, or exclude ad-blockers from the domain.

Example fix

// before
const mermaidInstance = await loadMermaid();
if (!mermaidInstance) {
  throw new Error('Failed to load mermaid library');
}
// after — reset the cached promise on failure so a retry can succeed
const loadMermaid = () => {
  if (typeof window === 'undefined') return Promise.resolve(null);
  if (!mermaidPromise) {
    mermaidPromise = import('mermaid').then((m) => m.default).catch((e) => {
      mermaidPromise = null; // allow next call to retry
      throw e;
    });
  }
  return mermaidPromise;
};
Defensive patterns

Strategy: fallback

Validate before calling

// Skip Mermaid rendering outside the browser
if (typeof window === 'undefined') return null; // don't call fetchSvg during SSR

Type guard

function isMermaidLoaded(m: unknown): m is typeof import('mermaid').default {
  return m != null && typeof (m as any).parse === 'function' && typeof (m as any).render === 'function';
}

Try / catch

try {
  const mermaid = await loadMermaid();
  if (!mermaid) throw new Error('Failed to load mermaid library');
} catch (err) {
  setValidContent(null); // show fallback / raw source instead of crashing the message
}

Prevention

When it happens

Trigger: The Mermaid code block tries to render during server-side rendering (Next.js SSR) where `window` is undefined; the browser cannot load the `mermaid` chunk (network failure, ad blocker/ CSP blocking the dynamic import, chunk hash mismatch after a redeploy); the mermaid package is missing or mis-versioned in the build.

Common situations: Deploying a new build while users hold an old one (chunk not found / stale hash); strict CSP without `script-src` allowing the bundled chunk; offline/poor connectivity during first Mermaid render (the ~2MB chunk fails to load); SSR/SSG rendering message content that includes Mermaid blocks; ad-blockers stripping the dynamic import.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/dccd25942783c8b1. Report an issue: GitHub.