mermaid-js/mermaid · error · Error

Root node is required

Error message

Root node is required

What it means

Third guard in validateLayoutData: `data` and `data.config` are present but `data.rootNode` is missing. cose-bilkent is a force-directed layout rooted at a primary node (used for mindmap-like layouts), so a rootNode is mandatory. Thrown at layout.ts:65.

Source

Thrown at packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/layout.ts:65

  }
}

/**
 * Validate layout data structure
 * @param data - The data to validate
 * @returns True if data is valid, throws error otherwise
 */
export function validateLayoutData(data: LayoutData): boolean {
  if (!data) {
    throw new Error('Layout data is required');
  }

  if (!data.config) {
    throw new Error('Configuration is required in layout data');
  }

  if (!data.rootNode) {
    throw new Error('Root node is required');
  }

  if (!data.nodes || !Array.isArray(data.nodes)) {
    throw new Error('No nodes found in layout data');
  }

  if (!Array.isArray(data.edges)) {
    throw new Error('Edges array is required in layout data');
  }

  return true;
}

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Ensure the diagram-db transform sets data.rootNode to the central/root node id before layout.
  2. If using cose-bilkent directly, designate one node as root in the LayoutData you construct.
  3. Use the dagre layout for diagrams without a clear root (cose-bilkent is root-dependent).
  4. Log data.rootNode to confirm it is set and references an existing node id.

Example fix

// before
{ config, nodes, edges, layoutAlgorithm: 'cose-bilkent' }
// after
{ config, nodes, edges, layoutAlgorithm: 'cose-bilkent', rootNode: nodes[0].id }
Defensive patterns

Strategy: validation

Validate before calling

if (!data?.rootNode) throw new Error('LayoutData.rootNode missing — designate a root node');

Type guard

function hasRootNode(d: any): d is { rootNode: string } { return typeof d?.rootNode === 'string' && d.rootNode.length > 0; }

Try / catch

try { validateLayoutData(data); } catch (e) { if (/Root node is required/.test(String(e))) { data.rootNode = data.nodes[0]?.id; validateLayoutData(data); } else throw e; }

Prevention

When it happens

Trigger: A LayoutData whose graph has no designated root, e.g. { config, nodes, edges } with rootNode undefined. Happens if the diagram type routed to cose-bilkent doesn't compute a root (the layout expects one to anchor the layout tree).

Common situations: Routing a diagram type that has no natural root (e.g. a generic flowchart) to cose-bilkent, or a bug in the diagram-db layer that fails to assign rootNode from the parsed AST. cose-bilkent is opt-in (includeLargeFeatures) so this usually surfaces in custom integrations.

Related errors


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