Troubleshooting
Do it with an agent
diagramkit is failing in this repo. Run
npx diagramkit doctor --jsonandnpx diagramkit render . --dry-run --json, then use the JSON output to diagnose. Readnode_modules/diagramkit/llms-full.txtfor 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:
npx diagramkit --version./node_modules/.bin/diagramkit --versionnode ./node_modules/diagramkit/dist/cli/bin.mjs --versionCurrent 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:
npx diagramkit warmupThis downloads the Playwright Chromium binary. Run it once per machine or CI environment.
If warmup fails, check that Playwright dependencies are installed:
npx playwright install-deps chromiumnpx diagramkit warmupNote
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:
npm add sharpsharp 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:
diagramkit render . --forceOr delete the manifest to reset tracking:
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:
- Disable contrast optimization to see the raw output:
diagramkit render . --no-contrast- Use neutral fills in Mermaid diagrams — bright neon colors (high luminance) are darkened to meet WCAG contrast thresholds
- Draw.io and Excalidraw handle dark mode in their own renderers —
--no-contrasthas 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:
- Ensure the file extension is supported (
.mermaid,.mmd,.excalidraw,.drawio, etc.) - Check that the file is not inside
node_modules/,.git/, or the configured output directory - 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:
npx diagramkit render . --quiet --jsonFor the JavaScript API:
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:
- Lifecycle cleanup — scripts should call
dispose()afterrenderAll()/renderFile()runs. - sharp detection — if raster output fails, ensure
sharpis installed in the same package where rendering runs. - Config validation fallback — invalid config values are reset to defaults with warnings; check logs for warnings about
outputDir,manifestFile, ordefaultFormats. - 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 LR ↔ flowchart 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:
{ 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:
diagramkit render . --format png --scale 1The 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:
{ 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:
- Check the manifest is enabled —
useManifest: true(default) - Filter by type if you only need one engine:
--type mermaid - Use
inputDirsto restrict scanning to specific directories:
{ inputDirs: ['docs/diagrams', 'src/architecture'],}- Graphviz is fastest — it uses WASM, no browser needed
- Mermaid, Excalidraw, Draw.io share a single Chromium instance and render concurrently across engine types