{"record":{"id":"a169a114a8b33329","repo":"mermaid-js/mermaid","slug":"both-layout-algorithms-algorithm-and-fallback","errorCode":null,"errorMessage":"Both layout algorithms ${algorithm} and ${fallback} are not registered.","messagePattern":"Both layout algorithms (.+?) and (.+?) are not registered\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/rendering-util/render.ts","lineNumber":149,"sourceCode":"  }\n\n  return layoutRenderer.render(data4Layout, svg, internalHelpers, {\n    algorithm: layoutDefinition.algorithm,\n  });\n};\n\n/**\n * Get the registered layout algorithm. If the algorithm is not registered, use the fallback algorithm.\n */\nexport const getRegisteredLayoutAlgorithm = (algorithm = '', { fallback = 'dagre' } = {}) => {\n  if (algorithm in layoutAlgorithms) {\n    return algorithm;\n  }\n  if (fallback in layoutAlgorithms) {\n    log.warn(`Layout algorithm ${algorithm} is not registered. Using ${fallback} as fallback.`);\n    return fallback;\n  }\n  throw new Error(`Both layout algorithms ${algorithm} and ${fallback} are not registered.`);\n};\n","sourceCodeStart":131,"sourceCodeEnd":151,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/rendering-util/render.ts#L131-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure registerDefaultLayoutLoaders() (or registerLayoutLoaders with at least dagre) has run before calling getRegisteredLayoutAlgorithm.","Don't override the fallback to an unregistered algorithm; rely on the default 'dagre' fallback.","If using a custom build, explicitly register the loaders you need at app init.","Check that the module side-effect import of render.ts isn't being tree-shaken away."],"exampleFix":"// before — registry empty, custom unregistered fallback\ngetRegisteredLayoutAlgorithm('cose-bilkent', { fallback: 'myAlgo' });\n// after\nimport { registerLayoutLoaders } from './render.js';\nregisterLayoutLoaders([{ name: 'dagre', loader: async () => await import('./dagre/index.js') }]);\ngetRegisteredLayoutAlgorithm('cose-bilkent'); // falls back to dagre","handlingStrategy":"fallback","validationCode":"function pickLayout(algorithm: string, fallback = 'dagre'): string {\n  // assume registry exposed; else hardcode known defaults\n  const known = ['dagre', 'swimlane', 'cose-bilkent'];\n  return known.includes(algorithm) ? algorithm : known.includes(fallback) ? fallback : 'dagre';\n}","typeGuard":"function isRegistered(algo: string, registry: Record<string, unknown>): algo is string { return algo in registry; }","tryCatchPattern":"try { return getRegisteredLayoutAlgorithm(algo, { fallback }); } catch (e) { if (/not registered/.test(String(e))) { registerLayoutLoaders([dagreLoader]); return 'dagre'; } throw e; }","preventionTips":["Keep the default 'dagre' fallback — don't override it to an unregistered algo.","Ensure registerDefaultLayoutLoaders() side-effect import isn't tree-shaken.","Register needed loaders explicitly in custom builds."],"tags":["layout","render","registry","configuration"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}