{"record":{"id":"a1cc042391489a36","repo":"mermaid-js/mermaid","slug":"no-nodes-found-in-layout-data-a1cc04","errorCode":null,"errorMessage":"No nodes found in layout data","messagePattern":"No nodes found in layout data","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/layout.ts","lineNumber":69,"sourceCode":" * Validate layout data structure\n * @param data - The data to validate\n * @returns True if data is valid, throws error otherwise\n */\nexport function validateLayoutData(data: LayoutData): boolean {\n  if (!data) {\n    throw new Error('Layout data is required');\n  }\n\n  if (!data.config) {\n    throw new Error('Configuration is required in layout data');\n  }\n\n  if (!data.rootNode) {\n    throw new Error('Root node is required');\n  }\n\n  if (!data.nodes || !Array.isArray(data.nodes)) {\n    throw new Error('No nodes found in layout data');\n  }\n\n  if (!Array.isArray(data.edges)) {\n    throw new Error('Edges array is required in layout data');\n  }\n\n  return true;\n}\n","sourceCodeStart":51,"sourceCodeEnd":78,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/layout.ts#L51-L78","documentation":"Fourth guard in validateLayoutData: `data.nodes` is missing or is not an array. The layout needs a list of nodes to position; without one cytoscape has nothing to lay out. Thrown at layout.ts:69. Note an empty array [] passes this check (it only rejects undefined/non-array).","triggerScenarios":"A LayoutData where nodes was never populated (e.g. a diagram whose parser produced zero nodes and the field was left undefined), or where nodes was set to a non-array (an object/Map). The check is `!data.nodes || !Array.isArray(data.nodes)`.","commonSituations":"An empty or fully-clustered diagram that yields no concrete nodes, a transform that assigns a Map instead of an array, or a mock fixture missing the field. Also if a cluster-only graph collapses all nodes into subgraphs leaving nodes empty/undefined.","solutions":["Ensure the diagram-db layer always emits data.nodes as an array (even if empty).","If clustering removes all leaf nodes, either retain at least the cluster nodes or skip layout for that case.","Validate with Array.isArray(data.nodes) before calling the layout and short-circuit if absent.","Use the standard render pipeline which guarantees the array shape."],"exampleFix":"// before\n{ config, rootNode, edges, layoutAlgorithm: 'cose-bilkent' } // nodes missing\n// after\n{ config, rootNode, nodes: [...], edges, layoutAlgorithm: 'cose-bilkent' }","handlingStrategy":"validation","validationCode":"if (!Array.isArray(data?.nodes)) throw new Error('LayoutData.nodes must be an array');","typeGuard":"function hasNodesArray(d: any): d is { nodes: unknown[] } { return Array.isArray(d?.nodes); }","tryCatchPattern":"try { validateLayoutData(data); } catch (e) { if (/No nodes found/.test(String(e))) { data.nodes = []; validateLayoutData(data); } else throw e; }","preventionTips":["Always emit nodes as an array (empty allowed).","Don't store nodes in a Map/object; convert before layout.","Validate the array shape upstream."],"tags":["layout","cose-bilkent","validation","graph"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}