( Robust / WCAG 4.1.2 )

ARIA attribute has an invalid value

CriticalLevel AWCAG 4.1.2 — Name, Role, Value

What is this issue?

An aria-* attribute has a real, correctly-spelled name, but the value assigned to it isn’t one the WAI-ARIA specification defines as valid for that specific attribute. Each ARIA attribute has its own value type: aria-hidden and aria-required are booleans that accept only the literal strings "true" or "false"; aria-checked is a tristate that also accepts "mixed"; aria-expanded is a boolean; ID-reference attributes like aria-labelledby expect a value matching another element’s id.

A value like "yes", "1", or a free-text string where the specification requires one of a fixed set of tokens fails this check, even though the attribute name itself is entirely correct. This is a narrower, more specific failure than a misspelled attribute name: the name is right, but the content inside it doesn’t match the type of value that attribute is defined to hold.

Why does this matter?

An invalid attribute value isn’t interpreted loosely or guessed at by the browser; it’s treated exactly as if the attribute had never been set. aria-expanded="yes" doesn’t get rounded to the nearest valid boolean; it’s discarded entirely, and the element reports no expand/collapse state at all, which is functionally worse than reporting the wrong state, since the user gets no information rather than confusing information.

The failure is especially costly on attributes describing state a user actively relies on to make a decision. A menu button using aria-expanded="1" to indicate it’s open looks correct to a developer reading the DOM, since “1” reads as “true” in plain English, but assistive technology never receives a valid expand state at all, so a screen reader user may be told a menu is collapsed when it’s actually open, or hear nothing about its state whatsoever, right at the moment they need to decide whether to activate it.

Who is affected?

  • Screen reader users: receive no state information at all for the affected attribute, since an invalid value is discarded rather than approximated, leaving them without the confirmation they need to know a control’s current condition.
  • Cognitive disabilities: lose a reliable state cue that would otherwise confirm whether an action, like opening a menu or checking a box, actually took effect, increasing uncertainty during a task.

What users experience

Farrukh uses JAWS on Windows to navigate a site’s mega menu built from a nested set of expandable sections. The “Shop by category” toggle uses aria-expanded="1" instead of "true", a value copied from a different framework’s boolean convention during a component migration. JAWS doesn’t recognize "1" as a valid boolean, so it announces the toggle with no expand or collapse state at all, no matter how many times Farrukh activates it. He opens the section, closes it, and reopens it, listening each time for confirmation JAWS never gives him, eventually giving up and tabbing through every link inside the menu manually to make sure he hasn’t missed anything.

How do I fix it?

Replace the invalid value with one of the specific values the WAI-ARIA specification defines for that attribute: for a boolean attribute like aria-expanded, that means the exact literal strings "true" or "false", nothing else. This works because assistive technology only recognizes these specific, spec-defined value formats; the moment the value matches one exactly, the browser passes the correct state through to the accessibility tree.

Check the value type each attribute expects before assuming a value “close enough” to the intended meaning will work; booleans need exactly "true"/"false", tristates additionally allow "mixed", and token attributes like aria-autocomplete only accept specific words from a fixed list ("inline", "list", "both", or "none"), not any descriptive string that seems reasonable. Keep the value in sync with the control’s real state via the same script that changes its visible appearance, so a technically-valid value doesn’t drift into an inaccurate one over time.

Code Examples

Before
<button aria-expanded="yes">Shop by category</button>
<div aria-hidden="1">Decorative divider</div>
<input aria-required="required">
After
<button aria-expanded="true">Shop by category</button>
<div aria-hidden="true">Decorative divider</div>
<input aria-required="true">

Each fix replaces a plausible-looking but invalid value with the exact literal boolean string the specification defines: "true" or "false", not "yes", "1", or the attribute’s own name repeated as its value. None of the three attributes needed a name change or restructuring; the failure in every case was purely the value not matching the type that specific attribute requires.

Common Mistakes

Mistake: “1 and 0 are standard boolean values in programming, so they should work here too.” ARIA boolean attributes are HTML attribute values, evaluated as literal strings by the accessibility tree, not as programming-language booleans coerced from truthy or falsy values. Only the exact strings "true" and "false" are valid; "1", "0", "yes", and "no" all fail regardless of how standard they are in other contexts.

Mistake: “The value describes the state accurately in plain English, so it should be understandable.” Assistive technology doesn’t interpret ARIA attribute values with natural-language understanding; it does an exact match against the specification’s defined value set for that attribute. A value can be perfectly clear to a human reading the source and still be completely invalid to the accessibility tree.

Mistake: “aria-required=‘required’ mirrors how the HTML required attribute works, so it should be consistent.” The native HTML required attribute is a boolean presence attribute: its mere presence means true, regardless of its value. aria-required is a different kind of attribute entirely, requiring an explicit "true" or "false" string value; mixing the two conventions produces a value ARIA doesn’t recognize.

How RedFlag Detects This

Automated: axe-core rule, runs on every scan. RedFlag calls axe-core’s aria-valid-attr-value rule as part of every scan, restricted to the WCAG 2.0/2.1/2.2 A and AA rule set. The rule reads every correctly-named aria-* attribute’s value and checks it against the specific value type the WAI-ARIA specification defines for that attribute (boolean, tristate, token list, ID reference, integer, or number), flagging any value that doesn’t match.

False negative: the rule confirms a value is structurally valid for its type; it can’t confirm the value is accurate to the control’s real current state: aria-expanded="false" on a menu that’s visually open still passes this specific check even though the value is wrong for what’s actually on screen. False positive: an ID-reference attribute like aria-labelledby pointing at an element that renders slightly after the initial scan (a common pattern in client-rendered single-page apps) can be flagged even though the reference resolves correctly once the full page has rendered, worth a manual re-check on any single-page-app component before treating it as a genuine failure. Manual step: confirm the flagged attribute’s value, once corrected to a valid format, is also being kept accurate to the control’s real, current state as a user interacts with it.

Manual Testing

  1. Open the page in Chrome or Firefox with NVDA or JAWS running.
  2. Tab to or activate the control whose state is set via an ARIA attribute (a menu toggle, a checkbox, an expandable section).
  3. Listen for a state announcement. It should reflect the control’s real, current condition accurately, changing correctly as you interact with it.
  4. If the screen reader announces no state at all, or a state that contradicts what’s visually happening on screen, check the attribute’s raw value in the DOM against the specification’s expected format for that attribute.
  5. Open the browser’s accessibility inspector (Chrome DevTools → Elements → Accessibility pane) and confirm the computed property shows the expected state; a blank or unexpected value here confirms the raw attribute value isn’t being recognized.

4.1.2 Name, Role, Value: Every interface component must expose its current state and value to assistive technology in a form it can interpret. An invalid attribute value fails this criterion because the value, though present in the markup, never resolves to anything the accessibility tree recognizes.

ARIA attribute name is not valid is the companion check for the same class of attribute: this rule assumes the attribute name is already correct and checks the value inside it instead.

ARIA role is invalid covers the equivalent value-validity problem on the role attribute specifically, rather than on aria-* state and property attributes.

ARIA attribute is not valid for the current role value and ARIA attribute is not allowed for this role both assume the attribute’s value format is already valid; this rule’s failure needs fixing before those checks are even meaningful.

aria-hidden=“true” is present on the document body and Focusable element is inside an aria-hidden container both concern aria-hidden specifically: a boolean attribute where an invalid value like "1" produces the same kind of silent failure this rule generally documents.

References

Frequently asked questions

What value types does aria-valid-attr-value check against?

The WAI-ARIA specification defines several value types per attribute: true/false booleans, tristate values (true, false, or mixed), token lists from a fixed set of allowed words, ID references pointing at another element's id, and numbers. Each attribute is checked against its own specific type, not a single universal rule.

Is aria-hidden="1" the same as aria-hidden="true"?

No. aria-hidden is a boolean attribute that only accepts the literal string values "true" or "false". "1" is not a recognized boolean value in the ARIA specification, so aria-hidden="1" fails this check and is treated as if the attribute were not set at all, meaning the element stays visible to assistive technology.

Why does an invalid attribute value get treated as unset, instead of just being ignored with the last known-good value kept?

ARIA attributes have no concept of a "last known good value" to fall back to, since the browser reads the current DOM state fresh each time. An invalid value simply fails validation and the attribute is treated as absent, which for a boolean state like aria-expanded means assistive technology reports no expand/collapse state at all rather than guessing the previous one.

Do ID-reference attributes like aria-labelledby fail this check if the referenced id does not exist yet?

Yes, functionally. If aria-labelledby points at an id that is not present in the DOM at the time it is evaluated, the reference resolves to nothing, so the element ends up with no accessible name from that source, the same practical outcome as an outright invalid value even though the string itself is technically well-formed.

Are aria-valid-attr and aria-valid-attr-value the same check under a different name?

No, they check two different things. aria-valid-attr verifies the attribute NAME itself is a real, correctly-spelled ARIA attribute. aria-valid-attr-value assumes the name is correct and instead verifies the VALUE inside that attribute is one the specification permits for that specific attribute.