danny-avila/LibreChat · error · Error

Mermaid diagram has invalid export dimensions

Error message

Mermaid diagram has invalid export dimensions

What it means

Thrown by `resolveCanvasDimensions` when the source width or height is not a finite positive number. This guard protects the canvas pixel-budget math (scale = min of PNG_EXPORT_SCALE=2, 16384/max-dim, sqrt(16777216/area)). Non-finite/zero/negative dimensions would break the scale calculation and produce a degenerate canvas, so it fails fast. The source dimensions come from the rendered Mermaid SVG's measured `naturalWidth`/`width` or from caller-supplied `dimensions`.

Source

Thrown at client/src/utils/diagram/export.ts:178

      resolve(reader.result);
    };
    reader.onerror = () => reject(new Error('Failed to prepare Mermaid SVG for PNG export'));
    reader.readAsDataURL(blob);
  });
}

function loadSvgImage(url: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = () => reject(new Error('Failed to load Mermaid SVG for PNG export'));
    image.src = url;
  });
}

export function resolveCanvasDimensions(width: number, height: number): MermaidDimensions {
  if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
    throw new Error('Mermaid diagram has invalid export dimensions');
  }

  const scale = Math.min(
    PNG_EXPORT_SCALE,
    MAX_CANVAS_DIMENSION / width,
    MAX_CANVAS_DIMENSION / height,
    Math.sqrt(MAX_CANVAS_PIXELS / (width * height)),
  );

  /* Round down: rounding each side independently can carry the product back
   * over the pixel budget the scale was chosen to satisfy, and a canvas above
   * that area makes `toBlob` fail outright in browsers that enforce it. */
  return {
    width: Math.max(1, Math.floor(width * scale)),
    height: Math.max(1, Math.floor(height * scale)),
  };
}

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Ensure the Mermaid SVG is rendered in a visible, laid-out container before export (the hook should measure after paint).
  2. If the SVG lacks width/height, parse the `viewBox` attribute and derive dimensions from it before calling export.
  3. Validate the measured dimensions are finite positive numbers before invoking `downloadMermaidPng`.
  4. If the diagram genuinely has no intrinsic size, supply explicit `dimensions` from the caller.

Example fix

// before
const sourceWidth = dimensions?.width || image.naturalWidth || image.width;
const sourceHeight = dimensions?.height || image.naturalHeight || image.height;
const canvasDimensions = resolveCanvasDimensions(sourceWidth, sourceHeight);
// after — fall back to viewBox when intrinsic width/height are missing
const vb = svg.viewBox?.baseVal;
const sourceWidth = dimensions?.width || image.naturalWidth || image.width || vb?.width;
const sourceHeight = dimensions?.height || image.naturalHeight || image.height || vb?.height;
if (!sourceWidth || !sourceHeight) throw new Error('Mermaid SVG has no measurable dimensions');
const canvasDimensions = resolveCanvasDimensions(sourceWidth, sourceHeight);
Defensive patterns

Strategy: validation

Validate before calling

// Validate measured dimensions before exporting
function isValidDimensions(w: unknown, h: unknown): boolean {
  return Number.isFinite(w) && Number.isFinite(h) && (w as number) > 0 && (h as number) > 0;
}
if (!isValidDimensions(sourceWidth, sourceHeight)) throw new Error('SVG has no measurable dimensions');

Type guard

function isPositiveFinite(n: unknown): n is number {
  return typeof n === 'number' && Number.isFinite(n) && n > 0;
}

Try / catch

try {
  const dims = resolveCanvasDimensions(sourceWidth, sourceHeight);
} catch (err) {
  if (err.message === 'Mermaid diagram has invalid export dimensions') {
    // fall back to viewBox-derived dimensions or abort export gracefully
  }
}

Prevention

When it happens

Trigger: The Mermaid SVG rendered but reported zero/undefined dimensions (e.g. `display:none` container, SVG with no `viewBox`/`width`/`height`, or measured before layout settled); the caller passed a `dimensions` object with NaN/0; the SVG's width/height attributes are missing and `naturalWidth` fell back to 0.

Common situations: Exporting a Mermaid diagram that was rendered in a hidden/offscreen container (clientWidth/Height 0); an SVG missing width/height/viewBox; exporting before the browser has laid out the SVG; a custom diagram type Mermaid rendered as empty markup.

Related errors


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