Skip to content

fix(aria-valid-attr-value): handle multiple aria-errormessage IDs#4973

Merged
straker merged 9 commits into
dequelabs:developfrom
JustasMonkev:fix/aria-errormessage-multiple-idrefs-4957
Jan 26, 2026
Merged

fix(aria-valid-attr-value): handle multiple aria-errormessage IDs#4973
straker merged 9 commits into
dequelabs:developfrom
JustasMonkev:fix/aria-errormessage-multiple-idrefs-4957

Conversation

@JustasMonkev

Copy link
Copy Markdown
Contributor

When aria-errormessage contains multiple space-separated IDs, the check now correctly verifies that all IDs are present in aria-describedby instead of failing to match the entire string against tokenized values.

Closes: #4957

@JustasMonkev JustasMonkev requested a review from a team as a code owner December 27, 2025 06:04
@CLAassistant

CLAassistant commented Dec 27, 2025

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@JustasMonkev JustasMonkev changed the title fix(checks): handle multiple ID tokens in aria-errormessage with aria… fix(checks): handle multiple ID tokens in aria-errormessage Dec 27, 2025
@JustasMonkev JustasMonkev changed the title fix(checks): handle multiple ID tokens in aria-errormessage fix(checks): handle multiple aria-errormessage IDs Dec 27, 2025
@straker

straker commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for the pr. Unfortunately it isn't an accessibility violation if all the aria-describedby ids are not present. As long as one exists then we want to pass this check.

@JustasMonkev

Copy link
Copy Markdown
Contributor Author

Thanks for the pr. Unfortunately it isn't an accessibility violation if all the aria-describedby ids are not present. As long as one exists then we want to pass this check.

Thanks for the comment, updated it

@JustasMonkev

Copy link
Copy Markdown
Contributor Author

@straker could you please check again?

@straker

straker commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

Sorry for the delay. I've been out of office and so haven't had time to look at this. After discussing this with the team here is what we are thinking.

Testing multiple aria-errormessage ids with various screen readers and browsers, only JAWS/Chrome supports this. NVDA/Firefox only announces the first id, while VoiceOver/Safari doesn't announce any. This means that even if multiple ids are supported by the spec, only JAWS/Chrome actually support it. When cases such as this happen with ARIA attributes, we typically report this as "unsupported" and that it's not widely supported by screen readers.

Taking that into consideration, as well as the various edge cases that would need to be handled to support multiple ids (what happens if the first id isn't on the page but all others are, what happens if the last id is the only one on the page, etc.), we feel it's best to report multiple ids on aria-errormessage as unsupported.

What this would mean is that we would update the aria-errormessage check to provide a new failure message of "Multiple IDs in aria-errormessage is not widely supported in assistive technologies" and in the evaluate function check if the tokenList of aria-errormessage contains more than 2 entires, and if so set the this.data({ message: 'unsupported' }) and return false.

@JustasMonkev

Copy link
Copy Markdown
Contributor Author

Sorry for the delay. I've been out of office and so haven't had time to look at this. After discussing this with the team here is what we are thinking.

Testing multiple aria-errormessage ids with various screen readers and browsers, only JAWS/Chrome supports this. NVDA/Firefox only announces the first id, while VoiceOver/Safari doesn't announce any. This means that even if multiple ids are supported by the spec, only JAWS/Chrome actually support it. When cases such as this happen with ARIA attributes, we typically report this as "unsupported" and that it's not widely supported by screen readers.

Taking that into consideration, as well as the various edge cases that would need to be handled to support multiple ids (what happens if the first id isn't on the page but all others are, what happens if the last id is the only one on the page, etc.), we feel it's best to report multiple ids on aria-errormessage as unsupported.

What this would mean is that we would update the aria-errormessage check to provide a new failure message of "Multiple IDs in aria-errormessage is not widely supported in assistive technologies" and in the evaluate function check if the tokenList of aria-errormessage contains more than 2 entires, and if so set the this.data({ message: 'unsupported' }) and return false.

Thanks for the comment, updated it

@straker straker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the changes. This is almost done but needs a few more tests. There should be an integration test or 2 in aria-valid-attr-value that tests multiple ids on aria-errormessage returns false. To do this add the HTML to the file with a unique id, then add that ID to the corresponding JSON file in the violations section.

@JustasMonkev

Copy link
Copy Markdown
Contributor Author

Thanks for the changes. This is almost done but needs a few more tests. There should be an integration test or 2 in aria-valid-attr-value that tests multiple ids on aria-errormessage returns false. To do this add the HTML to the file with a unique id, then add that ID to the corresponding JSON file in the violations section.

Added the tests

@JustasMonkev JustasMonkev requested a review from straker January 23, 2026 19:29
@JustasMonkev JustasMonkev requested a review from straker January 26, 2026 18:45

@straker straker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Awesome, thanks again for all the help!

Reviewed for security

@straker straker changed the title fix(checks): handle multiple aria-errormessage IDs fix(aria-valid-attr-value): handle multiple aria-errormessage IDs Jan 26, 2026
@straker straker merged commit 0489e30 into dequelabs:develop Jan 26, 2026
22 of 23 checks passed
WilcoFiers pushed a commit that referenced this pull request Mar 30, 2026
)

When aria-errormessage contains multiple space-separated IDs, the check
now correctly verifies that all IDs are present in aria-describedby
instead of failing to match the entire string against tokenized values.

Closes: #4957
straker pushed a commit that referenced this pull request Mar 30, 2026
)

When aria-errormessage contains multiple space-separated IDs, the check
now correctly verifies that all IDs are present in aria-describedby
instead of failing to match the entire string against tokenized values.

Closes: #4957
@straker straker mentioned this pull request Mar 30, 2026
WilcoFiers added a commit that referenced this pull request Mar 31, 2026
### [4.11.2](v4.11.1...v4.11.2)
(2026-03-30)

### Bug Fixes

- **aria-valid-attr-value:** handle multiple aria-errormessage IDs
([#4973](#4973))
([9322148](9322148))
- **aria:** prevent getOwnedVirtual from returning duplicate nodes
([#4987](#4987))
([99d1e77](99d1e77)),
closes [#4840](#4840)
- **DqElement:** avoid calling constructors with cloneNode
([#5013](#5013))
([88bc57f](88bc57f))
- **existing-rule:** aria-busy now shows an error message for a use with
unallowed children
([#5017](#5017))
([dded75a](dded75a))
- **scrollable-region-focusable:** clarify the issue is in safari
([#4995](#4995))
([2567afd](2567afd)),
closes
[WebKit#190870](https://github.com/dequelabs/WebKit/issues/190870)
[WebKit#277290](https://github.com/dequelabs/WebKit/issues/277290)
- **scrollable-region-focusable:** do not fail scroll areas when all
content is visible without scrolling
([#4993](#4993))
([240f8b5](240f8b5))
- **target-size:** determine offset using clientRects if target is
display:inline
([#5012](#5012))
([69d81c1](69d81c1))
- **target-size:** ignore widgets that are inline with other inline
elements ([#5000](#5000))
([cf8a3c0](cf8a3c0))
WilcoFiers added a commit that referenced this pull request Jun 1, 2026
##
[4.12.0](v4.11.4...v4.12.0)
(2026-06-01)

### Features

- add gather-internals.js external script
([#5099](#5099))
([c61d58b](c61d58b)),
closes [#5080](#5080)
- **aria-allowed/prohibited-attr, aria-required-parent/children:**
partially support element internals role
([#5080](#5080))
([417b48a](417b48a)),
closes [#5039](#5039)
[#4259](#4259)
- **axe.externalAPIs:** add public api for setting elementInternal data
([#5105](#5105))
([63bab8f](63bab8f))
- **core:** expose normalizeRunOptions
([#4998](#4998))
([b8e6a59](b8e6a59))
- expose axe.resetLocale() to restore the default locale
([#5108](#5108))
([c2b5292](c2b5292)),
closes [#5107](#5107)
- **getRules:** include rule enabled state in returned objects
([#5118](#5118))
([75bf772](75bf772)),
closes [#5116](#5116)
- **list,listitem:** support element internals role
([#5119](#5119))
([7d9d696](7d9d696))
- **new-rule:** check that aria-tab have an accessible name
([#5001](#5001))
([0d4e4e7](0d4e4e7)),
closes [#4842](#4842)
- **rules:** deprecate landmark-complementary-is-top-level rules
([#4992](#4992))
([9e09139](9e09139)),
closes [#4950](#4950)
- **utils:** add `getElementInternals` function
([#5077](#5077))
([1c15f82](1c15f82))

### Bug Fixes

- **aria-allowed-attr:** restrict br and wbr elements to aria-hidden
only ([#4974](#4974))
([c6245e7](c6245e7))
- **aria-conditional-attr:** add support for radio
([#5100](#5100))
([8223c98](8223c98))
- **aria-valid-attr-value:** handle multiple aria-errormessage IDs
([#4973](#4973))
([0489e30](0489e30))
- **aria:** prevent getOwnedVirtual from returning duplicate nodes
([#4987](#4987))
([48ca955](48ca955)),
closes [#4840](#4840)
- **commons/text:** exclude natively hidden elements from
aria-labelledby accessible name
([#5076](#5076))
([ea7202c](ea7202c)),
closes [#4704](#4704)
- **DqElement:** avoid calling constructors with cloneNode
([#5013](#5013))
([0281fa1](0281fa1))
- **existing-rule:** aria-busy now shows an error message for a use with
unallowed children
([#5017](#5017))
([2067b87](2067b87))
- **helpUrl:** ensure axe.configure always updates the help URLs
([#5114](#5114))
([c4f60ff](c4f60ff))
- **label-content-name-mismatch:** match visible text with aria-label
and exclude invisible text
([#5096](#5096))
([3a012a1](3a012a1))
- **locale:** ensure all subtags are correctly set
([#5112](#5112))
([13005ed](13005ed))
- **scrollable-region-focusable:** clarify the issue is in safari
([#4995](#4995))
([4ec5211](4ec5211)),
closes
[WebKit#190870](https://github.com/dequelabs/WebKit/issues/190870)
[WebKit#277290](https://github.com/dequelabs/WebKit/issues/277290)
- **scrollable-region-focusable:** do not fail scroll areas when all
content is visible without scrolling
([#4993](#4993))
([838707a](838707a))
- **target-size:** determine offset using clientRects if target is
display:inline
([#5012](#5012))
([a4b8091](a4b8091))
- **target-size:** ignore position: fixed elements that are offscreen
when page is scrolled
([#5066](#5066))
([1229a6e](1229a6e)),
closes [#5065](#5065)
- **target-size:** ignore widgets that are inline with other inline
elements ([#5000](#5000))
([a8dd81b](a8dd81b))
- **utils/getAncestry:** escape node name
([#5079](#5079))
([d1fabaa](d1fabaa)),
closes [#5078](#5078)
- **utils:** Add null check to parseCrossOriginStylesheet, closes
[#5074](#5074)
([#5075](#5075))
([f12ef32](f12ef32))
- **utils:** update isShadowRoot to use spec-compliant custom element
regex ([#5059](#5059))
([edc6ce2](edc6ce2)),
closes [#5030](#5030)

This PR was opened by a robot 🤖 🎉
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aria-valid-attr-value does not correctly handle multiple id tokens for aria-errormessage with aria-describedby

3 participants