Website problems
ARIA references pointing nowhere
ARIA attributes that reference other elements by identifier only work when the identifier exists. When it does not, the reference produces nothing: a control with a broken label reference has no accessible name, and a screen reader announces its role and stops. Nothing about the page looks wrong — the visual label renders exactly as intended — which is why this survives review and why it belongs in an automated check.
What a broken reference costs
A label reference that resolves to nothing leaves the control unnamed: a screen reader says the role and nothing else.
A description reference that resolves to nothing silently drops the help text under a form field, including error messages.
A reference used to associate a control with the content it controls leaves that relationship unstated.
A reference naming the element that describes a region leaves the region unlabelled in the landmark list.
In each case the failure is total for that attribute rather than partial, because there is nothing to fall back to.
Why it happens mechanically rather than carelessly
A component library generates identifiers per instance while the reference is hard-coded, so only the first instance on a page resolves.
A server-rendered identifier changes during hydration, leaving the reference pointing at a value that existed for one frame.
A label is removed during a redesign and its reference is left behind in a component nobody re-read.
An identifier is renamed and the references to it are not, because nothing in the toolchain checks them.
Duplicate identifiers on one page, where a reference resolves to whichever the browser picks and frequently the wrong one.
The ordering rule worth knowing
When several naming mechanisms are present, they are consulted in a fixed order and the first that yields a name wins.
A label reference takes precedence over a label string attribute, which takes precedence over a native label element.
So a broken label reference on a control that also has a perfectly good native label produces no name, because the broken reference was consulted first and the process does not fall back.
That is the most surprising instance of this problem and the one people argue about before testing it.
Which is an argument for using the native label element alone wherever it will do the job.
How to fix it
Make identifiers unique and generated in the same place as the reference, so the two cannot drift.
Prefer a native label element wrapping or referencing the field, which associates without a separate identifier where it wraps.
Where a reference is genuinely needed, generate both ends from one value in the component.
Add a check to the build or the test suite that resolves every reference, which is a few lines and catches the whole class.
Remove references that are no longer needed rather than leaving them pointing at removed content.
How to check it yourself
Search the served markup for the reference attributes and collect the identifiers they name.
Confirm each identifier exists exactly once in the document.
Inspect the accessibility tree in developer tools, which shows the computed name for each control — an empty name is the defect.
Test with a screen reader on the forms specifically, since that is where the consequence is largest.
Check pages with repeated components, where the per-instance identifier problem concentrates.
How VeriFixScan detects it
`accessibility.aria_references` verifies that reference attributes point at identifiers that exist, which is this problem directly.
`accessibility.aria_validity` validates roles, states and properties against the specification.
`accessibility.aria_hidden` reports interactive elements hidden from assistive technology, which is the neighbouring silent failure.
`accessibility.autocomplete` and `accessibility.form_errors` cover the rest of what a form field needs beyond its name.
`structure.html_quality` reports duplicated identifiers, which make a reference resolve unpredictably.
Why no ARIA beats broken ARIA
Native elements carry their semantics without any attribute: a button element is announced as a button everywhere.
ARIA overrides those semantics, so a broken or wrong attribute replaces something correct with something that is not.
A control with no ARIA and a native label is named correctly; the same control with a broken reference is not named at all.
Which makes the first question on any finding here whether the attribute was needed, before asking what it should point at.
Frequently asked questions
- My field has a visible label. Why is it reported as unnamed?
- Because a broken labelledby reference is consulted before the native label and does not fall back. The visual label renders correctly and contributes nothing to the accessible name.
- Why does only the first component on the page work?
- Almost always a per-instance generated identifier against a hard-coded reference. The first match resolves and every later one points at the wrong element or at nothing.
- Should I just remove the ARIA attributes?
- Frequently yes. A native label element does the job without a separate identifier, and no ARIA is better than ARIA that overrides correct semantics with nothing.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website