mermaid-js/mermaid · error · Error

Both layout algorithms

Error message

Both layout algorithms ${algorithm} and ${fallback} are not registered.

What it means

Thrown by getRegisteredLayoutAlgorithm when neither the requested `algorithm` nor the `fallback` (default 'dagre') exists in layoutAlgorithms. Normally a missing algorithm silently falls back to dagre with a warning, so this throw means the fallback itself is unavailable — i.e. the default loaders were never registered or were cleared.

Solutions

  1. Ensure registerDefaultLayoutLoaders() (or registerLayoutLoaders with at least dagre) has run before calling getRegisteredLayoutAlgorithm.
  2. Don't override the fallback to an unregistered algorithm; rely on the default 'dagre' fallback.
  3. If using a custom build, explicitly register the loaders you need at app init.
  4. Check that the module side-effect import of render.ts isn't being tree-shaken away.

Example fix

// before — registry empty, custom unregistered fallback
getRegisteredLayoutAlgorithm('cose-bilkent', { fallback: 'myAlgo' });
// after
import { registerLayoutLoaders } from './render.js';
registerLayoutLoaders([{ name: 'dagre', loader: async () => await import('./dagre/index.js') }]);
getRegisteredLayoutAlgorithm('cose-bilkent'); // falls back to dagre
Defensive patterns

Strategy: fallback

Validate before calling

function pickLayout(algorithm: string, fallback = 'dagre'): string {
  // assume registry exposed; else hardcode known defaults
  const known = ['dagre', 'swimlane', 'cose-bilkent'];
  return known.includes(algorithm) ? algorithm : known.includes(fallback) ? fallback : 'dagre';
}

Type guard

function isRegistered(algo: string, registry: Record<string, unknown>): algo is string { return algo in registry; }

Try / catch

try { return getRegisteredLayoutAlgorithm(algo, { fallback }); } catch (e) { if (/not registered/.test(String(e))) { registerLayoutLoaders([dagreLoader]); return 'dagre'; } throw e; }

Prevention

When it happens

Trigger: Calling getRegisteredLayoutAlgorithm('cose-bilkent', { fallback: 'dagre' }) in an environment where registerDefaultLayoutLoaders hasn't run or layoutAlgorithms was emptied, or passing a custom fallback that also isn't registered. The render.ts module calls registerDefaultLayoutLoaders() at import (line 60), so this implies that didn't happen.

Common situations: Importing getRegisteredLayoutAlgorithm from a tree-shaken/minimal bundle that dropped the default-loader side effect, a test that mocks the registry empty, or a custom fallback name passed in config that was never registered. Rare in normal mermaid usage because dagre is always default-registered.

Related errors


AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12). Data as JSON: /api/errors/a169a114a8b33329. Report an issue: GitHub.

Appendix: source

Thrown at packages/mermaid/src/rendering-util/render.ts:149

  }

  return layoutRenderer.render(data4Layout, svg, internalHelpers, {
    algorithm: layoutDefinition.algorithm,
  });
};

/**
 * Get the registered layout algorithm. If the algorithm is not registered, use the fallback algorithm.
 */
export const getRegisteredLayoutAlgorithm = (algorithm = '', { fallback = 'dagre' } = {}) => {
  if (algorithm in layoutAlgorithms) {
    return algorithm;
  }
  if (fallback in layoutAlgorithms) {
    log.warn(`Layout algorithm ${algorithm} is not registered. Using ${fallback} as fallback.`);
    return fallback;
  }
  throw new Error(`Both layout algorithms ${algorithm} and ${fallback} are not registered.`);
};

View on GitHub (pinned to d93e9c88c0)