{"record":{"id":"9d69bd647aa8cdf7","repo":"mermaid-js/mermaid","slug":"node-node-label-is-missing-coordinates","errorCode":null,"errorMessage":"Node \"${node.label}\" is missing coordinates","messagePattern":"Node \"(.+?)\" is missing coordinates","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/diagrams/wardley/wardleyBuilder.ts","lineNumber":191,"sourceCode":"   * (handles pipeline components which have synthetic IDs like \"Parent_Child\").\n   */\n  public resolveNodeId(name: string): string {\n    if (this.nodes.has(name)) {\n      return name;\n    }\n    for (const [id, node] of this.nodes) {\n      if (node.label === name) {\n        return id;\n      }\n    }\n    return name;\n  }\n\n  public build(): WardleyBuildResult {\n    const nodes: WardleyNode[] = [];\n    for (const node of this.nodes.values()) {\n      if (typeof node.x !== 'number' || typeof node.y !== 'number') {\n        throw new Error(`Node \"${node.label}\" is missing coordinates`);\n      }\n      nodes.push(node as WardleyNode & { x: number; y: number });\n    }\n    return {\n      nodes,\n      links: [...this.links],\n      trends: [...this.trends.values()],\n      pipelines: [...this.pipelines.values()],\n      annotations: [...this.annotations],\n      notes: [...this.notes],\n      accelerators: [...this.accelerators],\n      deaccelerators: [...this.deaccelerators],\n      annotationsBox: this.annotationsBox,\n      axes: { ...this.axes },\n      size: this.size,\n    };\n  }\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/diagrams/wardley/wardleyBuilder.ts#L173-L209","documentation":"wardleyBuilder.build() walks every node and requires numeric x and y coordinates before producing the layout result; any node still missing coordinates (x or y not a number) throws, naming the node label. This prevents rendering nodes at undefined positions.","triggerScenarios":"A component declared without coordinates (no visibility/evolution pair), or one whose coordinate parsing was skipped/failed, reaching build(). Pipelines/notes that synthesise nodes without setting x/y can also surface here if their parent lacked coords.","commonSituations":"Declaring `component Foo` with no `[x, y]` label; a typo in the coordinate label format so the parser never assigns x/y; a node added via the db API directly without coordinates; version change in label syntax.","solutions":["Give the named component a coordinate label, e.g. `component Foo [0.5, 0.8]`.","Verify the coordinate label syntax matches the current wardley grammar.","If building programmatically, set node.x and node.y (numbers) before build().","Check that notes/pipelines reference parents that already have coordinates."],"exampleFix":"// before\ncomponent Foo\n\n// after\ncomponent Foo [0.5, 0.8]","handlingStrategy":"validation","validationCode":"// Require numeric coordinates on every node before build()\nfor (const node of builder.getNodes?.() ?? []) {\n  if (typeof node.x !== 'number' || typeof node.y !== 'number') {\n    throw new Error(`Node ${node.label} needs coordinates`);\n  }\n}\nbuilder.build();","typeGuard":"const hasCoords = (n): n is WardleyNode =>\n  typeof n?.x === 'number' && typeof n?.y === 'number';","tryCatchPattern":"try {\n  builder.build();\n} catch (e) {\n  if (e instanceof Error && /missing coordinates/.test(e.message)) {\n    // read the node label from the message and assign [x, y]\n  } else { throw e; }\n}","preventionTips":["Always declare components with a [visibility, evolution] label.","Validate coordinates upstream with the same rule as toPercent.","Ensure pipeline parents have coordinates before referencing them."],"tags":["wardley","coordinates","builder","validation"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}