Artifact live mermaid renderer (pinned to 11.16.1) lays out complex flowcharts incorrectly — edges bundle at subgraph borders, implying wrong dependencies
Summary
An Artifact's live mermaid renderer (/_runtime/mermaid-11.16.1.min.js, injected automatically for any HTML artifact containing <pre class="mermaid">) lays out a complex multi-subgraph flowchart incorrectly — several edges get bundled together where they cross a subgraph border, visually implying dependencies that don't exist in the source. The identical mermaid source renders correctly under a newer mermaid version (11.17.2, via @mermaid-js/mermaid-cli).
This isn't a caching or "stale artifact" issue — I confirmed that directly:
- Fetched the published artifact's raw HTML server-side (
action: "read") — source was correct/unchanged. - Republished to a brand-new artifact ID — same bad layout, ruling out any per-artifact cache/version pinning.
- Rendered the exact same
.mmdsource through mermaid 11.16.1 (downloaded straight fromunpkg.com/mermaid@11.16.1/dist/mermaid.min.js, loaded in a local headless Chromium page with the samemermaid.initialize()config the artifact runtime uses) and got the same bad layout. - Rendered the same source through mermaid 11.17.2 (
npx @mermaid-js/mermaid-cli) and got a correct layout.
So this is specifically a mermaid-version layout regression between 11.16.1 and 11.17.2 on this class of diagram (many subgraphs, several edges that connect a node in one subgraph to a node several subgraphs away).
Repro
Paste the mermaid source below into any Artifact HTML inside <pre class="mermaid">...</pre>, publish, and view it.
Expected: every edge visually traceable to exactly the two nodes it connects (e.g. full_Deals → airbyte_full_Deals only, full_Users → integration_users only).
Actual (on the live Artifact, mermaid 11.16.1): edges leaving the received_keyed/ subgraph bundle together at the border before diverging, making it look like every node in that subgraph feeds every node in the intermediates//DIRECT subgraphs (e.g. full_Users visually appears to feed airbyte_full_Deals, which has no edge to it in the source).
<details>
<summary>Full repro source (~150 lines)</summary>
flowchart LR
classDef raw fill:#9aa0a6,stroke:#6f757c,color:#16202b;
classDef merge fill:#f28e2b,stroke:#bd6d15,color:#241200;
classDef view fill:#4e79a7,stroke:#31597f,color:#fff;
classDef tbl fill:#e15759,stroke:#b23a3c,color:#fff;
classDef fork fill:#edc948,stroke:#b89a1f,color:#241200;
subgraph REC["received/ — unchanged"]
direction TB
R_ACC["Accounts"]
R_CON["Contacts"]
R_LEA["Leads"]
R_DEA["Deals"]
R_USR["Users"]
R_CAL["Calls"]
R_EVE["Events"]
R_FM["Field_Metadata"]
R_NOT["Notes"]
R_TAS["Tasks"]
end
subgraph RDP["raw_data_product/ — 10 views, one per stream, plain SELECT * over received/, admits duplicates"]
direction TB
V_ACC["Accounts"]
V_CON["Contacts"]
V_LEA["Leads"]
V_DEA["Deals"]
V_USR["Users"]
V_CAL["Calls"]
V_EVE["Events"]
V_FM["Field_Metadata"]
V_NOT["Notes"]
V_TAS["Tasks"]
end
subgraph KEY["received_keyed/ — merge, _written_at, enableCursor, no bucketBy, no enableChangeHistory"]
direction TB
K_ACC["full_Accounts — + name, domain_name"]
K_CON["full_Contacts — + name, account_id"]
K_LEA["full_Leads — + name, domain_name"]
K_DEA["full_Deals — + name, account_id"]
K_USR["full_Users"]
K_CAL["full_Calls"]
K_EVE["full_Events"]
K_FM["full_Field_Metadata"]
K_NOT["full_Notes"]
K_TAS["full_Tasks"]
end
subgraph DIRECT["integration_data_product/ — reads received_keyed/ directly, no intermediate"]
direction TB
O_IC["integration_contacts"]
O_PROPS["properties"]
O_IU["integration_users"]
end
subgraph INT["integration_data_product/intermediates/"]
direction TB
I_FDEA["airbyte_full_Deals"]
I_ENG["airbyte_full_engagements"]
I_FOBJ["full_objects"]
I_OM["objects_mapped"]
I_OP["object_properties"]
I_LINE["airbyte_full_opportunity_line_items"]
end
subgraph IDP["integration_data_product/ — outputs"]
direction TB
F_AA["activities_augmented"]
F_LEC["lifecycle_events_configured"]
F_LECD["lifecycle_events_custom_dimensions_mapped"]
F_VMCD["volume_metrics_with_custom_dimensions"]
F_VMA["volume_metrics_augmented"]
O_IA["integration_activities"]
O_IOBJ["integration_objects"]
O_IOP["integration_object_properties"]
O_CAV["customer_accounts_with_virtuals"]
O_ICA["integration_customer_accounts"]
O_ICAOC["integration_customer_account_ownership_changes"]
O_ILE["integration_lifecycle_events"]
O_ILELI["integration_lifecycle_event_line_items"]
O_ICDVS["integration_custom_dimension_values_sourced"]
end
R_ACC --> K_ACC
R_CON --> K_CON
R_LEA --> K_LEA
R_DEA --> K_DEA
R_USR --> K_USR
R_CAL --> K_CAL
R_EVE --> K_EVE
R_FM --> K_FM
R_NOT --> K_NOT
R_TAS --> K_TAS
R_ACC --> V_ACC
R_CON --> V_CON
R_LEA --> V_LEA
R_DEA --> V_DEA
R_USR --> V_USR
R_CAL --> V_CAL
R_EVE --> V_EVE
R_FM --> V_FM
R_NOT --> V_NOT
R_TAS --> V_TAS
K_FM --> O_PROPS
K_CON --> O_IC
K_LEA --> O_IC
K_USR --> O_IU
K_DEA --> I_FDEA
K_ACC --> I_FOBJ
K_CON --> I_FOBJ
K_LEA --> I_FOBJ
I_FDEA --> I_FOBJ
K_CAL --> I_ENG
K_EVE --> I_ENG
I_FOBJ --> I_OM
I_FOBJ --> I_OP
I_FOBJ --> O_IOBJ
I_OP --> O_IOP
I_OM --> O_CAV
O_CAV --> O_ICA
I_ENG --> F_AA
F_AA --> O_IA
I_FOBJ --> F_LEC
F_LEC --> F_LECD
F_LEC --> F_VMCD
F_LECD --> F_VMCD
F_VMCD --> F_VMA
F_VMA --> O_ILE
F_VMA --> O_ICAOC
O_ILE --> O_ILELI
I_LINE --> O_ILELI
I_OM --> O_ICDVS
F_LECD --> O_ICDVS
class R_ACC,R_CON,R_LEA,R_DEA,R_USR,R_CAL,R_EVE,R_FM,R_NOT,R_TAS raw;
class K_ACC,K_CON,K_LEA,K_DEA,K_USR,K_CAL,K_EVE,K_FM,K_NOT,K_TAS,I_FDEA,I_ENG,I_FOBJ,I_OM,I_OP merge;
class V_ACC,V_CON,V_LEA,V_DEA,V_USR,V_CAL,V_EVE,V_FM,V_NOT,V_TAS,O_PROPS,O_IC,O_IU,O_IA,O_IOBJ,O_IOP,O_ICA,O_ICAOC,O_ILE,O_ILELI,O_ICDVS view;
class I_LINE,O_CAV tbl;
class F_AA,F_LEC,F_LECD,F_VMCD,F_VMA fork;
linkStyle default stroke:#8a94a3,stroke-width:1.3px;
</details>
Environment
- Product: Claude Code Artifacts (
claude.ai/code/artifact/...) - Live runtime observed in the published artifact's injected script tag:
<script src="/_runtime/mermaid-11.16.1.min.js"> - Confirmed-good version: mermaid 11.17.2 (current
@mermaid-js/mermaid-clidefault at time of testing)
Impact
Any moderately complex flowchart Artifact (multiple subgraphs, a handful of edges that skip past an adjacent subgraph) can render with misleading edge topology — worse than illegible, actively wrong — with no visible error and no way to tell from the source alone. Republishing, hard-refreshing, or creating a brand-new artifact ID does not help, since the bug is in the pinned renderer version, not the artifact content or any cache.
Workaround
Render the diagram locally with a mermaid version that lays it out correctly (e.g. @mermaid-js/mermaid-cli, currently resolves to 11.17.2), export to SVG, and embed that static SVG directly in the artifact instead of a live <pre class="mermaid"> block. This sidesteps the artifact's pinned live renderer entirely.
Suggested fix
Bump the artifact runtime's bundled mermaid version past whatever introduced this dagre layout regression (somewhere between 11.16.1 and 11.17.2), or make the version configurable/current.