Skip to content

Fix/5741 unique marker ids - #5756

Closed
Bunker-D wants to merge 20 commits into
mermaid-js:developfrom
Bunker-D:fix/5741_unique_marker_ids
Closed

Bunker-D wants to merge 20 commits into
mermaid-js:developfrom
Bunker-D:fix/5741_unique_marker_ids

Conversation

@Bunker-D

@Bunker-D Bunker-D commented Aug 24, 2024 •

Copy link
Copy Markdown

📑 Summary

Ensures unique IDs for the markers. This extends merge #4825, to cover C4 context diagrams, Entity Relationship diagrams, Requirement diagram, Sequence diagrams, Timelines, and User Journeys.

Resolves #5741, #1318 and #3267 (that were closed while only partially resolved), mjbvz/vscode-markdown-mermaid/#270.

Also, adds classes to the markers for future and/or custom styling purposes.

📏 Design Decisions

Markers IDs are replaced by <svg_id>-<marker_id>, where:

  • <svg_id> is the ID of the SVG element (the Mermaid diagram)
  • <marker_id> is the previously used id.

The added classes use the format: mermaid-marker-<diagram_type>-<marker_id> (e.g., mermaid-marker-er-ONLY_ONE_END), where <diagram_type> is a shorthand for the diagram type:

  • C4 Context (C4Context) → c4
  • Entity Relation diagram (erDiagram) → er
  • User Journey (journey) → journey
  • Requirements (requirementDiagram) → req
  • Sequence (sequenceDiagram) → seq
  • Timeline (timeline) → tl

Those changes have also been implemented for seemingly unused markers found in the code.

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added necessary unit/e2e tests.
  • 📓 have added documentation. Make sure MERMAID_RELEASE_VERSION is used for all new features.
  • 🦋 If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

@changeset-bot

changeset-bot Bot commented Aug 24, 2024 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 3dcaa5e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions Bot added the Type: Bug / Error Something isn't working or is incorrect label Aug 24, 2024
@netlify

netlify Bot commented Aug 24, 2024 •

Copy link
Copy Markdown

✅ Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 57de0c8
🔍 Latest deploy log https://app.netlify.com/sites/mermaid-js/deploys/66e8a6c96f1c9500089247cd
😎 Deploy Preview https://deploy-preview-5756--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@codecov

codecov Bot commented Aug 24, 2024 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 1.01010% with 98 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.53%. Comparing base (7a86fd7) to head (3dcaa5e).
⚠️ Report is 3118 commits behind head on develop.

Files with missing lines Patch % Lines
.esbuild/build.ts 0.00% 37 Missing ⚠️
.esbuild/util.ts 0.00% 27 Missing ⚠️
.build/common.ts 8.33% 11 Missing ⚠️
.esbuild/server.ts 0.00% 11 Missing ⚠️
.build/jsonSchema.ts 0.00% 4 Missing ⚠️
.build/types.ts 0.00% 3 Missing ⚠️
.vite/server.ts 0.00% 3 Missing ⚠️
.vite/build.ts 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           develop   #5756      +/-   ##
==========================================
- Coverage     5.00%   3.53%   -1.47%     
==========================================
  Files          337     491     +154     
  Lines        48213   49003     +790     
  Branches       576     766     +190     
==========================================
- Hits          2413    1733     -680     
- Misses       45800   47270    +1470     
Flag Coverage Δ
unit 3.53% <1.01%> (-1.47%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.vite/build.ts 0.88% <0.00%> (+0.88%) ⬆️
.build/types.ts 4.00% <0.00%> (+4.00%) ⬆️
.vite/server.ts 0.00% <0.00%> (ø)
.build/jsonSchema.ts 0.00% <0.00%> (ø)
.build/common.ts 2.63% <8.33%> (+2.63%) ⬆️
.esbuild/server.ts 0.94% <0.00%> (+0.94%) ⬆️
.esbuild/util.ts 0.00% <0.00%> (ø)
.esbuild/build.ts 0.00% <0.00%> (ø)

... and 485 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@argos-ci

argos-ci Bot commented Aug 24, 2024 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 6 added Mar 6, 2026, 1:49 AM

@Bunker-D

Bunker-D commented Aug 24, 2024 •

Copy link
Copy Markdown
Author

I don't know why Lint fails here on GitHub (the “Some checks were not successful”). It works fine on my machine.

Of note too: vitest run fails on my machine… because of gitGraph, which is not something I changed. (I don't think it failed before I updated my fork today.)

Comment thread CONTRIBUTING.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this file from the PR?

@pkg-pr-new

pkg-pr-new Bot commented Sep 16, 2024 •

Copy link
Copy Markdown

Open in StackBlitz

@mermaid-js/examples

npm i https://pkg.pr.new/@mermaid-js/examples@5756

mermaid

npm i https://pkg.pr.new/mermaid@5756

@mermaid-js/layout-elk

npm i https://pkg.pr.new/@mermaid-js/layout-elk@5756

@mermaid-js/layout-tidy-tree

npm i https://pkg.pr.new/@mermaid-js/layout-tidy-tree@5756

@mermaid-js/mermaid-zenuml

npm i https://pkg.pr.new/@mermaid-js/mermaid-zenuml@5756

@mermaid-js/parser

npm i https://pkg.pr.new/@mermaid-js/parser@5756

@mermaid-js/tiny

npm i https://pkg.pr.new/@mermaid-js/tiny@5756

commit: 4ee0e79

@HowieHz

HowieHz commented Nov 4, 2025

Copy link
Copy Markdown

What's the status of this PR? @Bunker-D

@sidharthv96

Copy link
Copy Markdown
Member

@Bunker-D can you please sync with latest develop?

@shubhamparikh2704 please add this to our agenda for next meeting.

@alexander-turner

alexander-turner commented Feb 19, 2026 •

Copy link
Copy Markdown
Contributor

@sidharthv96 @shubhamparikh2704 Any news? This would resolve a11y issues on my site.

@netlify

netlify Bot commented Mar 6, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 3dcaa5e
🔍 Latest deploy log https://app.netlify.com/projects/mermaid-js/deploys/69aa304ec1ceab00082b4c71
😎 Deploy Preview https://deploy-preview-5756--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Bunker-D

Bunker-D commented Mar 6, 2026 •

Copy link
Copy Markdown
Author

I updated the PR with the current version of Mermaid.

I removed my changed to Entity Relation (er) diagrams has the issue had been solved since my original PR. But I kept the dedicated Cypress test.

Edit: And yes, the results of the new tests in argos are what is expected, i.e., the markers (arrows etc) are visible even though there is a hidden version of the graph (style="visibility: hidden") before the visible one.

@knsv

knsv commented Mar 12, 2026

Copy link
Copy Markdown
Collaborator

I will work with my code assistant to review the PR, will be reviewing the reviewer at the same time.

@knsv-bot knsv-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sisyphus-bot]

Thank you for this contribution, @Bunker-D — this is an important quality-of-life fix that affects a lot of users, and you've done the hard work of tracking down all the affected diagram types. The two-diagram test pattern (one hidden, one visible on the same page) is exactly the right approach to catch marker ID collisions. Let's get this across the finish line!


What's working well

🎉 The two-diagram test pattern in the cypress HTML fixtures is spot-on. Rendering a hidden diagram first and then a visible one is the correct way to expose duplicate-ID issues — well designed.

🎉 Adding CSS classes (mermaid-marker-*) alongside the ID fix is a great forward-looking addition, giving diagram consumers a stable hook for custom styling.

🎉 The fix mechanism itself — threading id as a parameter to all marker-insertion functions — is clean and consistent with how PR #4825 handled the same problem for flowcharts, class diagrams, and state diagrams.

🎉 Good JSDoc updates on the modified functions.


Things to address

🔴 [blocking] ER diagram markers not fixed — but Cypress test was added

The PR includes cypress/integration/rendering/marker_unique_id_er.spec.js and cypress/platform/marker_unique_id_er.html, which correctly puts two ER diagrams on the same page to expose the duplicate-ID bug. However, the actual fix for ER markers was not implemented.

packages/mermaid/src/diagrams/er/erMarkers.js still defines all ten markers using global string IDs (ONLY_ONE_START, ZERO_OR_ONE_END, etc.) via its insertMarkers(elem, conf) function, and erRenderer.js:581 calls it without passing id. The marker references at erRenderer.js:463–502 use url(#ZERO_OR_ONE_END) etc. — none prefixed with the diagram's id.

The Cypress test will show the broken rendering (disappearing markers on the second diagram) unless erMarkers.js:insertMarkers() is updated to accept id and prefix each .attr('id', ...) call, and erRenderer.js is updated to pass id both to insertMarkers and to each url(#...) reference.

🔴 [blocking] Sequence diagram: four arrowhead markers still use global IDs

The PR updates insertArrowHead, insertArrowFilledHead, insertArrowCrossHead, and insertSequenceNumber in sequence/svgDraw.js. But there are four more marker-insertion functions in the same file that were missed:

  • insertSolidTopArrowHead — id: 'solidTopArrowHead' (line 1717)
  • insertSolidBottomArrowHead — id: 'solidBottomArrowHead' (line 1732)
  • insertStickTopArrowHead — id: 'stickTopArrowHead' (line 1747)
  • insertStickBottomArrowHead — id: 'stickBottomArrowHead' (line 1765)

These are called in sequenceRenderer.ts at lines 1060–1063 without the id parameter, and referenced at sequenceRenderer.ts:566–607 without the id prefix (e.g., url(#solidTopArrowHead)). All four have the same collision risk.

There is also a filled-head-control marker defined inline inside the actor-drawing path (sequence/svgDraw.js:690) that is never prefixed. Since its definition and reference are co-located within the same actor draw call, the collision risk is lower in practice — but it's still a global ID that should be prefixed for consistency.

The current Cypress test for sequence only exercises arrowhead, filled-head, and crosshead. Adding a test case with SOLID_TOP, SOLID_BOTTOM, STICK_TOP, and STICK_BOTTOM message types would catch the four missed markers above.

🟡 [important] Missing changeset

This is a user-facing bug fix that resolves long-standing issues (#1318, #3267, #5741) affecting C4, ER, sequence, timeline, and journey diagrams. It needs a changeset for the mermaid package:

pnpm changeset
# select: mermaid, patch bump
# description: fix: ensure unique marker IDs per diagram to prevent arrow rendering issues

Security

No XSS or injection issues were found. The id values being concatenated into marker .attr('id', ...) calls are generated internally by Mermaid, not from user input. CSS class names are hardcoded strings. All user-provided text goes through .text() (not .html()), so it is properly escaped.


Summary: Two blocking issues: ER markers not yet fixed despite the test being added, and four sequence arrowhead markers missed. Once those are addressed and a changeset is added, this should be in great shape!

@Bunker-D

Copy link
Copy Markdown
Author

Well. Pull #7410 solved the issue, and pass the tests I added. An AI produced basically the same solution as me.

That being said, the AI didn't provide any tests. I also added classes for the markers whose IDs where modified, so that user can still relatively easily style said markers with CSS.

@knsv, do you want me to update my PR to include those elements? Or should we just close it?

@mermaid-js mermaid-js deleted a comment from knsv-bot Mar 13, 2026
@knsv

knsv commented Mar 13, 2026

Copy link
Copy Markdown
Collaborator

Hi @Bunker-D. Thank you for your patience, and I'm sorry this sat for so long before being reviewed. You were the first to identify, report, and start working on this fix, and you absolutely deserve credit for that.

PR #7410 has been merged and covers the same core bug (and then some), so the duplicate-marker issue should now be resolved in develop. This PR is no longer needed to fix the regression — feel free to close it.

That said, the CSS classes you added (mermaid-marker-*) are a nice bonus that #7410 doesn't include. If you'd like to contribute those as a standalone follow-up PR, we'd welcome that. It would be a small, clean, focused change and should be straightforward to merge. It would also in that case get full focus from us.

Thank you again for doing the groundwork here — this was a long-standing pain point for many users.

@knsv-bot

knsv-bot commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Hi @Bunker-D — closing this one out, as the underlying issue (#5741, duplicate marker/SVG element ids) was fixed and merged in #7410. As you noted, that landed essentially the same solution you'd identified, and your tests held up against it.

Credit where it's due: you were the first to identify, report, and fix this — thank you for the careful work and for your patience while it sat. The fix being in develop now is the only reason I'm closing this rather than merging it.

Really appreciate the contribution. 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Bug / Error Something isn't working or is incorrect

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicated IDs for markers (still)

6 participants