Summary
In architecture mode, the built-in router can produce a path that passes through an unrelated component's bounding box. Both render and validate accept the result without any error or warning.
Because arrows are painted before component boxes (correct per the design system), the offending segments hide behind the obstacle component and the arrow visually appears to originate from the obstacle, misrepresenting the topology.
Workflow mode already guards against this since v2.8 ("workflow rendering now rejects edges that cross through non-endpoint nodes" — status update in #10). Architecture mode has no equivalent check. This report is a concrete, minimal real-world case for the "shared obstacle detection across architecture/dataflow/lifecycle" follow-up mentioned there.
Repro
repro.architecture.json — 3 components, 1 connection, no route hints:
{
"schema_version": 1,
"diagram_type": "architecture",
"meta": {
"title": "Repro",
"subtitle": "arrow passes through an unrelated component",
"output": "repro.html"
},
"components": [
{ "id": "api", "type": "backend", "label": "API", "pos": [400, 280], "size": [160, 76] },
{ "id": "cache", "type": "database", "label": "Cache", "pos": [645, 130], "size": [130, 60] },
{ "id": "queue", "type": "cloud", "label": "Queue", "pos": [880, 130] }
],
"connections": [
{ "from": "api", "to": "queue", "variant": "dashed" }
],
"cards": []
}
node bin/archify.mjs render architecture repro.architecture.json repro.html # succeeds
node bin/archify.mjs validate architecture repro.architecture.json --json # passes
node bin/archify.mjs check repro.html # ok: true
Actual
The only connection in the file is api → queue, but it renders as if it were cache → queue:

Generated path:
M 560 318 L 712 318 Q 720 318 720 310 L 720 168 Q 720 160 728 160 L 880 160
The vertical run at x=720 (y 310 → 168) and the horizontal run at y=160 (x 728 → 880) both cross cache's bounding box x 645–775, y 130–190. The dashed arrow disappears behind the Cache box and re-emerges from its right edge, so it reads as Cache → Queue instead of API → Queue.
How we hit this in practice: in a 12-component diagram, an API → SQS connection rendered exactly like a Redis → SQS connection (the router chose a detour whose corner sat inside the Redis box). The first person who saw the diagram asked "why is Redis connected to SQS?" — i.e. the failure mode is silent and actively misleading, unlike a validation error.
Expected
Same behavior as workflow mode since v2.8: fail fast with an actionable hint (e.g. suggest via waypoints or different fromSide/toSide), or at minimum a warning from validate.
The check itself is cheap for orthogonal paths: axis-aligned segment vs. component rects (minus the two endpoint components, with a small margin). We ran exactly that as an external post-check to find all occurrences in our diagram.
Workaround
Manually routing with via waypoints around the obstacle works fine:
{ "from": "api", "to": "queue", "variant": "dashed",
"fromSide": "right", "toSide": "top", "via": [[620, 318], [620, 100], [940, 100]] }

Environment
- archify 2.11.0 (installed via
npx skills add tt-a1i/archify -g)
- Node v24.11.0, macOS
- Found while driving the skill from Claude Code — model
claude-fable-5, reasoning effort max
Summary
In architecture mode, the built-in router can produce a path that passes through an unrelated component's bounding box. Both
renderandvalidateaccept the result without any error or warning.Because arrows are painted before component boxes (correct per the design system), the offending segments hide behind the obstacle component and the arrow visually appears to originate from the obstacle, misrepresenting the topology.
Workflow mode already guards against this since v2.8 ("workflow rendering now rejects edges that cross through non-endpoint nodes" — status update in #10). Architecture mode has no equivalent check. This report is a concrete, minimal real-world case for the "shared obstacle detection across architecture/dataflow/lifecycle" follow-up mentioned there.
Repro
repro.architecture.json— 3 components, 1 connection, no route hints:{ "schema_version": 1, "diagram_type": "architecture", "meta": { "title": "Repro", "subtitle": "arrow passes through an unrelated component", "output": "repro.html" }, "components": [ { "id": "api", "type": "backend", "label": "API", "pos": [400, 280], "size": [160, 76] }, { "id": "cache", "type": "database", "label": "Cache", "pos": [645, 130], "size": [130, 60] }, { "id": "queue", "type": "cloud", "label": "Queue", "pos": [880, 130] } ], "connections": [ { "from": "api", "to": "queue", "variant": "dashed" } ], "cards": [] }Actual
The only connection in the file is
api → queue, but it renders as if it werecache → queue:Generated path:
The vertical run at
x=720(y 310 → 168) and the horizontal run aty=160(x 728 → 880) both crosscache's bounding boxx 645–775, y 130–190. The dashed arrow disappears behind the Cache box and re-emerges from its right edge, so it reads as Cache → Queue instead of API → Queue.How we hit this in practice: in a 12-component diagram, an
API → SQSconnection rendered exactly like aRedis → SQSconnection (the router chose a detour whose corner sat inside the Redis box). The first person who saw the diagram asked "why is Redis connected to SQS?" — i.e. the failure mode is silent and actively misleading, unlike a validation error.Expected
Same behavior as workflow mode since v2.8: fail fast with an actionable hint (e.g. suggest
viawaypoints or differentfromSide/toSide), or at minimum a warning fromvalidate.The check itself is cheap for orthogonal paths: axis-aligned segment vs. component rects (minus the two endpoint components, with a small margin). We ran exactly that as an external post-check to find all occurrences in our diagram.
Workaround
Manually routing with
viawaypoints around the obstacle works fine:{ "from": "api", "to": "queue", "variant": "dashed", "fromSide": "right", "toSide": "top", "via": [[620, 318], [620, 100], [940, 100]] }Environment
npx skills add tt-a1i/archify -g)claude-fable-5, reasoning effortmax