Skip to main content
On this page

Troubleshooting

Troubleshooting decision tree: common issues and quick fixes

Do it with an agent

diagramkit is failing in this repo. Run npx diagramkit doctor --json and npx diagramkit render . --dry-run --json, then use the JSON output to diagnose. Read node_modules/diagramkit/llms-full.txt for error code meanings. Common fixes: missing Chromium → npx diagramkit warmup; missing sharp for raster → npm add sharp; stale manifest → --force. Report the specific cause and the fix applied.

Do it manually

Local npm Bin Command Is Silent

Symptom: ./node_modules/.bin/diagramkit --version prints nothing, or npx diagramkit render ... exits without output.

Fix: upgrade to the latest patch release, then retry one of the supported startup paths:

Shell
npx diagramkit --version./node_modules/.bin/diagramkit --versionnode ./node_modules/diagramkit/dist/cli/bin.mjs --version

Current releases normalize symlinked npm bin paths to the real CLI entrypoint, so local npm bin shims, npx, and direct dist/cli/bin.mjs execution should behave the same.

Chromium Not Found

Error: Chromium browser not found. Run "diagramkit warmup" to install it.

Fix:

Shell
npx diagramkit warmup

This downloads the Playwright Chromium binary. Run it once per machine or CI environment.

If warmup fails, check that Playwright dependencies are installed:

Shell
npx playwright install-deps chromiumnpx diagramkit warmup

Note

Graphviz does not need Chromium. If you only render .dot/.gv files, warmup is not required.

sharp Not Installed

Error: sharp is required for png output. Install: npm add sharp

Fix:

Shell
npm add sharp

sharp is an optional peer dependency, only needed for raster formats (PNG, JPEG, WebP, AVIF). SVG output never requires sharp.

Diagram Renders as Empty or Blank

Mermaid: Check for syntax errors in the .mermaid file. Validate at mermaid.live.

Excalidraw: Ensure the file is raw .excalidraw JSON, not an exported SVG or PNG. The file must contain elements, appState, and files keys.

Draw.io: Ensure the file is the raw .drawio XML with an <mxGraphModel> root. Do not export as SVG from the Draw.io editor.

Graphviz: Validate DOT syntax at Graphviz Online.

Manifest Says “Up-to-Date” but Outputs Are Missing

The manifest tracks content hashes. If outputs were deleted but the manifest still exists, diagramkit detects the missing files and re-renders automatically.

If this does not happen, force a full re-render:

Shell
diagramkit render . --force

Or delete the manifest to reset tracking:

Shell
find . -name manifest.json -path '*/.diagramkit/*' -deletediagramkit render .

Dark Mode Colors Look Wrong

diagramkit post-processes dark SVGs to improve contrast for Mermaid and Graphviz. If colors appear too dark or desaturated:

  1. Disable contrast optimization to see the raw output:
Shell
diagramkit render . --no-contrast
  1. Use neutral fills in Mermaid diagrams — bright neon colors (high luminance) are darkened to meet WCAG contrast thresholds
  2. Draw.io and Excalidraw handle dark mode in their own renderers — --no-contrast has no effect on these engines

See Architecture for details on how each engine handles dark mode.

Watch Mode Stops Detecting Changes

The file watcher (chokidar) monitors supported extensions. If changes are not detected:

  1. Ensure the file extension is supported (.mermaid, .mmd, .excalidraw, .drawio, etc.)
  2. Check that the file is not inside node_modules/, .git/, or the configured output directory
  3. Symlinked files are skipped — use real files instead

CI Pipeline Hangs

The CLI automatically disposes the shared browser pool after normal non-watch renders. If a CI job hangs, the usual causes are:

  • a watch-mode process that is meant to stay alive
  • a custom script using the JavaScript API without calling dispose()
  • another long-running task waiting on stdin/stdout rather than render completion

For CLI usage, prefer a normal one-shot render:

Shell
npx diagramkit render . --quiet --json

For the JavaScript API:

TypeScript
import { renderAll, dispose } from 'diagramkit'try {  const result = await renderAll({ dir: '.', formats: ['svg', 'png'] })  if (result.failed.length > 0) process.exit(1)} finally {  await dispose()}

--no-manifest only disables incremental caching. It does not control browser lifecycle cleanup.

Agent-Specific Checks

When an AI agent is driving renders, verify these first:

  1. Lifecycle cleanup — scripts should call dispose() after renderAll()/renderFile() runs.
  2. sharp detection — if raster output fails, ensure sharp is installed in the same package where rendering runs.
  3. Config validation fallback — invalid config values are reset to defaults with warnings; check logs for warnings about outputDir, manifestFile, or defaultFormats.
  4. Retry behavior in watch mode — after a render failure, fix the source diagram and save again to re-trigger rendering.

Diagram Is Too Wide or Too Tall (ASPECT_RATIO_EXTREME)

Symptom: diagramkit validate emits an ASPECT_RATIO_EXTREME warning, or your flowchart LR renders at 12:1 and is unreadable when embedded at 650 px, or a Drawio diagram scales to 10% of native size in the docs viewport.

Diagrams that overflow typical doc widths (~650–800 px) get auto-scaled by the browser and lose ~39% of text legibility. The validator surfaces this as a warning so the agent loop can rebalance, split, or swap engine before shipping.

The fix is engine-specific but follows the same escalation ladder. Apply steps in order; advance only when the current step doesn’t bring the rendered SVG inside [1:1.9, 3.3:1]. Re-render with --force after each step.

Step 1 — Engine-local rebalance (try this first)

Engine Tactic
Mermaid Flip the directive (flowchart LRflowchart TB); set mermaidLayout: { mode: 'auto' } in diagramkit.config.json5.
Drawio Reflow <mxGeometry> rows / columns so the bounding box becomes more square.
Graphviz Add ratio="0.75" to the graph [...] defaults block; flip rankdir; add {rank=same; …} constraints.
Excalidraw Reflow shape positions per the layout grids in Excalidraw skill > Step 3.

For Mermaid specifically, the project default lives in diagramkit.config.json5:

Json5
{  mermaidLayout: { mode: 'auto', targetAspectRatio: 4 / 3, tolerance: 2.5 },}

mode: 'warn' (default) only logs; 'flip' / 'elk' / 'auto' actively rebalance. See Mermaid > Aspect-ratio rebalance for the full mode table.

Step 2 — Reduce / restructure

Merge low-information nodes; pull subgraphs into separate diagrams; cap branching width at 8 children per parent. Hard ceiling per diagram: ≤ 50 nodes (dense) / ≤ 100 (sparse), ≤ 100 connections, ≤ 8 parallel branches.

Step 3 — Split into multiple diagrams

Save as <name>-overview.<ext> + <name>-detail-<N>.<ext>. Embed both with <picture> blocks in the surrounding markdown. Splitting beats cramming whenever the diagram covers two unrelated concerns.

Step 4 — Swap engine (last resort)

When the engine itself is fighting the layout, convert the source to a different engine. The tradeoff: a textual rewrite in the new engine’s syntax.

Currently using Why it can’t fit Swap to
Mermaid (Dagre) No aspect-ratio knob; ELK plugin missing Graphviz (ratio="0.75" is direct); or Drawio for icon-heavy / precision layouts
Drawio Shape catalog isn’t the value Graphviz (algorithmic) or Mermaid (text-first structured types)
Graphviz Shape is naturally a structured Mermaid type Mermaid (sequence, ER, gantt, …)
Excalidraw Hand-drawn aesthetic isn’t the value Mermaid or Graphviz

Note on ELK: the mermaidLayout: { mode: 'elk' | 'auto' } modes inject an ELK directive but mermaid v11 doesn’t ship the layout engine by default. Install @mermaid-js/layout-elk if you need ELK to actually run; otherwise auto falls back to flip-only.

Eligibility for rebalance: only flowchart/graph diagrams in Mermaid can be rebalanced via direction flip. Sequence, gantt, journey, state, ER, class, mindmap, sankey, gitGraph diagrams are inherently directional — fix those by reducing or splitting at the source level.

Render Fails with Out-of-Memory

Large diagrams at high scale factors consume significant memory. Reduce the scale:

Shell
diagramkit render . --format png --scale 1

The default scale is 2 (retina). Scale 3+ is only recommended for print or large-format output. The maximum supported scale is 10.

Custom Extensions Not Recognized

Add custom extensions to your config file:

Json5
{  extensionMap: {    ".custom": "mermaid",  },}

The extension map is merged with built-in defaults. Use diagramkit render . --dry-run to verify which files would be discovered.

Performance: Many Files Are Slow

diagramkit uses incremental builds by default (manifest-based SHA-256 hashing). Only changed files re-render. If batch rendering is still slow:

  1. Check the manifest is enableduseManifest: true (default)
  2. Filter by type if you only need one engine: --type mermaid
  3. Use inputDirs to restrict scanning to specific directories:
Json5
{  inputDirs: ['docs/diagrams', 'src/architecture'],}
  1. Graphviz is fastest — it uses WASM, no browser needed
  2. Mermaid, Excalidraw, Draw.io share a single Chromium instance and render concurrently across engine types