[quality] Image alt text is double-escaped: /architectures/swisscom-kubernetes-service reads "CNIP & SKP"

Open
#2,084 4 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

  • #2085 by @hivecommons-hive — closed without merging
  • #2089 by @hivecommons-hive — closed without merging

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
28/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
javascript, react

Research direction

The bad alt text is authored at docs/architectures/swisscom-kubernetes-service/index.md line 85, and the importer's cleanMarkdown() in scripts/lib/architecture-content.mjs never inspects alt text. Work is already under way in open PR #2085, so check that branch before starting. Done means the page's alt reads plainly with the word 'and', plus a test under the docs and blog trees that fails on &, <, > or " in image alt text.

Written by the indexing model from the issue text.

Description

agent/quality blocked testing

Finding

On https://endusers.cncf.io/architectures/swisscom-kubernetes-service/ the
diagram's alternative text is announced and displayed as

Kubernetes Service is a combination of CNIP & SKP deliverables

The literal character sequence &amp; is in the text, not an ampersand. A
screen-reader user hears the entity spelled out, and the same string is what
the browser paints in place of the image when it fails to load.

Verified against the live site:

$ curl -sL https://endusers.cncf.io/architectures/swisscom-kubernetes-service/ \
    | grep -oE 'alt="[^"]*CNIP[^"]*"'
alt="Kubernetes Service is a combination of CNIP &amp;amp; SKP deliverables"

and against a local npm run build:production, reading the DOM property rather
than the markup, so this is not a curl artifact:

$ # chromium, img.alt on /architectures/swisscom-kubernetes-service/
["Kubernetes Service is a combination of CNIP &amp; SKP deliverables"]

The authored Markdown is correct — docs/architectures/swisscom-kubernetes-service/index.md
line 85 writes a plain &:

![Kubernetes Service is a combination of CNIP & SKP deliverables](./images/kubernetes-service-team-deliverables.png)

The double escape comes from Docusaurus. @docusaurus/mdx-loader 3.10.2
(lib/remark/transformImage/index.js) HTML-escapes the alt text while building
the JSX attribute:

attributes.push({ type: 'mdxJsxAttribute', name: 'alt', value: escapeHtml(node.alt) });

so the compiled chunk already carries the entity as literal text —

(0,i.jsx)(n.img,{alt:"Kubernetes Service is a combination of CNIP &amp; SKP deliverables", ...

— and React escapes the attribute a second time on render. Any authored alt
text containing &, <, > or " is affected. Today exactly one page is:

$ grep -rn '^!\[[^]]*&' docs blog --include='*.md' --include='*.mdx'
docs/architectures/swisscom-kubernetes-service/index.md:85:...

Nothing in the tree stops the next one. Architecture pages arrive through the
submission-issue importer with the submitter's prose, and cleanMarkdown()
(scripts/lib/architecture-content.mjs) rewrites image destinations only; it
never looks at alt text. The accessibility lane checks heading order and
contrast, not the content of an alt string.

Recommendation

Two parts, both in this repository — the upstream escape is Docusaurus's and is
not worth carrying a patch for:

  1. Fix the live page. In docs/architectures/swisscom-kubernetes-service/index.md
    line 85, write the conjunction as a word:

    ![Kubernetes Service is a combination of CNIP and SKP deliverables](./images/kubernetes-service-team-deliverables.png)
    

    This is the submitter's own meaning, unchanged, and it is the only form that
    survives the double escape intact.

  2. Add a contract test that reads the authored Markdown under docs/ and
    blog/ and fails when an image's alt text contains a character
    transformImage escapes (&, <, >, "), naming the file and the alt
    string and pointing the author at the plain-word spelling. Without it the
    defect returns with the next submission that writes & in a caption, and it
    returns silently: the build succeeds, the link check passes, and only a
    screen-reader user notices.

Priority

  • Impact: medium — one published page, degraded for assistive-technology users
    and for anyone whose image load fails; recurs unguarded.
  • Effort: low — a one-word content fix and one test file.

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: e3f4f9d

— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

Dominant language
JavaScript
Stars
0
Forks
6
Avg merge
6h 8m
Merged PRs (30d)
534

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cncf/endusers

All issues in cncf/endusers

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.