How to fix: Broken ARIA ID references
ARIA attributes that point to other elements, like aria-labelledby and aria-describedby, must reference the id of an element that actually exists in the page; fix each one to target a real, correctly spelled id.
What it is
Several ARIA attributes work by referencing another element's id rather than holding text themselves. aria-labelledby and aria-describedby point at the text that names or describes a control; aria-controls, aria-owns, and aria-flowto point at related elements; aria-activedescendant and aria-errormessage point at the active item or the error text. WCAG Success Criterion 4.1.2 Name, Role, Value depends on these references resolving so the name, description, or relationship is actually exposed.
A broken reference is one whose value does not match any id in the document. The browser resolves these attributes by id lookup, so if the target id is misspelled, never existed, or was removed in a refactor, the reference silently fails. An aria-labelledby that points at a missing id produces no name at all, which can be worse than having no aria-labelledby in the first place.
Two details cause most of these bugs. IDs are case-sensitive, so aria-labelledby="Title" will not match id="title". And a reference attribute can list multiple ids separated by spaces (aria-labelledby="label1 label2"), so a single typo or stray id in that list breaks the resolution. Duplicate ids in the page are another common cause, since the relationship becomes ambiguous.
Who it affects & why it matters
Screen reader users are affected most directly. When aria-labelledby or aria-describedby fails to resolve, a control loses its accessible name or its supporting description, so the user may hear an unlabeled field or miss critical instructions. A broken aria-errormessage means a validation error never gets announced.
It also affects users of widgets that rely on relationship attributes: a broken aria-controls or aria-activedescendant can leave a combobox, tablist, or listbox announcing the wrong state or none at all. Anyone depending on assistive technology to understand component relationships is impacted.
A broken ARIA reference is a Level A failure under SC 4.1.2, the most basic conformance tier, and WCAG 2.1 Level AA (which includes all Level A criteria) is the benchmark U.S. courts apply to ADA website claims. Because the failure silently removes a name or description, it often hides a second, more visible problem, such as an effectively unlabeled control, that a plaintiff's tooling will also flag.
These references usually sit on the most important interactive components, custom form fields, dialogs, and widgets, so a dangling id can break the exact element a user needs. Web accessibility lawsuits keep rising and disproportionately target businesses under $25 million in revenue, and fixing a reference is typically a one-line correction once you find the mismatched id.
How to fix it
- Find every aria-labelledby, aria-describedby, aria-controls, aria-owns, aria-flowto, aria-activedescendant, and aria-errormessage attribute on the page.
- For each one, confirm that every id it lists exists somewhere in the document, remembering that ids are case-sensitive.
- Where a reference is broken, either correct the value to match the real id, or add the missing target element with the right id.
- If an attribute lists multiple ids (space-separated), check each id in the list individually.
- Make sure target ids are unique across the page, since duplicate ids make the reference ambiguous, then re-scan.
<span id="email-label">Email address</span>
<input type="email" aria-labelledby="emailLabel">
<button aria-describedby="help-tip">Save</button><span id="email-label">Email address</span>
<input type="email" aria-labelledby="email-label">
<button aria-describedby="save-help">Save</button>
<span id="save-help">Saves your changes immediately.</span>How AccessKnight detects this
AccessKnight collects every element that uses aria-labelledby, aria-describedby, aria-controls, aria-owns, aria-flowto, aria-activedescendant, or aria-errormessage. For each of those attributes it splits the value on whitespace and looks up each id with getElementById; if any referenced id is not present in the document, the element is flagged and the specific missing id is named in the fix message. Because the check is case-sensitive and per-id, a single misspelled or stray id in a multi-id list is caught, and pointing the reference at the correct existing id resolves it.