mermaid-js/mermaid · error · Error
C4 rel "${rel.from}" -> "${rel.to}" references an unknown sh
Error message
C4 rel "${rel.from}" -> "${rel.to}" references an unknown shape What it means
Thrown by the C4 drawRels function when getC4ShapeObj(rel.from) or getC4ShapeObj(rel.to) returns undefined. Every relationship must reference a C4 shape (Person, System, Component, Container, Boundary, etc.) that has already been declared and is in scope. A miss means the alias does not resolve to any known shape.
Source
Thrown at packages/mermaid/src/diagrams/c4/c4Renderer.ts:397
rel.label.text = i + ': ' + rel.label.text;
}
let textLimitWidth = calculateTextWidth(rel.label.text, relConf as TextDimensionConfig);
calcC4ShapeTextWH('label', rel, relTextWrap, relConf, textLimitWidth);
if (rel.techn && rel.techn.text !== '') {
textLimitWidth = calculateTextWidth(rel.techn.text, relConf as TextDimensionConfig);
calcC4ShapeTextWH('techn', rel, relTextWrap, relConf, textLimitWidth);
}
if (rel.descr && rel.descr.text !== '') {
textLimitWidth = calculateTextWidth(rel.descr.text, relConf as TextDimensionConfig);
calcC4ShapeTextWH('descr', rel, relTextWrap, relConf, textLimitWidth);
}
const fromNode = getC4ShapeObj(rel.from);
const endNode = getC4ShapeObj(rel.to);
if (!fromNode || !endNode) {
throw new Error(`C4 rel "${rel.from}" -> "${rel.to}" references an unknown shape`);
}
const points = getIntersectPoints(fromNode, endNode);
if (!points.startPoint || !points.endPoint) {
throw new Error(
`Could not calculate intersection points for rel "${rel.from}" -> "${rel.to}"`
);
}
rel.startPoint = points.startPoint;
rel.endPoint = points.endPoint;
}
svgDraw.drawRels(diagram, rels, conf, diagramId);
};
async function drawInsideBoundary(
diagram: SVG,
parentBoundaryAlias: string,
parentBounds: Bounds,
currentBoundaries: C4Boundary[],View on GitHub (pinned to d93e9c88c0)
Solutions
- Verify both `from` and `to` aliases are declared earlier in the C4 DSL.
- Check spelling and case — aliases must match exactly.
- If a shape is inside a boundary, ensure the relationship is evaluated in a scope where that shape is visible.
Example fix
// before Person(personA, 'A') Rel(personA, systemZ, 'uses') // systemZ never declared // after Person(personA, 'A') System(systemZ, 'Z') Rel(personA, systemZ, 'uses')
Defensive patterns
Strategy: validation
Validate before calling
function assertRelTargetsExist(rel, resolveAlias) {
if (!resolveAlias(rel.from) || !resolveAlias(rel.to)) {
throw new Error(`Rel references unknown shape: ${rel.from} -> ${rel.to}`);
}
} Type guard
const relTargetsExist = (rel, resolveAlias) => Boolean(resolveAlias(rel.from)) && Boolean(resolveAlias(rel.to));
Prevention
- Declare every Person/System/Container/Component before any Rel that references it.
- Treat aliases as case-sensitive; reuse the exact declared alias string.
When it happens
Trigger: A C4 `Rel` directive whose `from` or `to` alias was never declared, was declared in a different (out-of-scope) boundary, or is misspelled. e.g. Rel(personA, systemZ, 'uses') where 'systemZ' is not defined.
Common situations: Typo in an alias; referencing a shape declared inside a different boundary that isn't propagated to the current scope; case mismatch (aliases are case-sensitive); renaming a shape without updating its relationships.
Related errors
- C4 shape "${fromNode.alias}" has no intersect function. Plea
- Could not calculate intersection points for rel "${rel.from}
- The left-hand id [${lhsId}] does not yet exist. Please creat
- The right-hand id [${rhsId}] does not yet exist. Please crea
- C4: no shape handler for "${node.shape}"
AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12).
Data as JSON: /api/errors/4e7402d978527798.
Report an issue: GitHub.