Fix Invalid or Misspelled ARIA Attributes

Learn how to fix aria-valid-attr issues in Lighthouse accessibility audits
Harlan WiltonHarlan Wilton4 min read Published

Misspelled ARIA attributes are ignored by assistive technologies, making your accessibility efforts invisible.

What's happening

ARIA attributes must match the exact specification. A typo like aria-lable instead of aria-label means screen readers see nothing at all. Browsers ignore invalid attributes without warning. Your element appears accessible in your code but provides zero information to users.

Diagnose

  1. Open Chrome DevTools (F12)
  2. Go to Elements panel
  3. Find the flagged element
  4. Look for attributes starting with aria-
  5. Check for typos or non-existent attribute names

Common misspellings:

  • aria-lablearia-label
  • aria-labelled-byaria-labelledby
  • aria-rolerole (aria-role doesn't exist)
  • aria-descriptionaria-describedby
  • aria-pressed on wrong elements

Fix

1. Correct typos

<!-- Before: Misspelled attribute -->
<button aria-lable="Close dialog">×</button>

<!-- After: Correct spelling -->
<button aria-label="Close dialog">×</button>

2. Use correct attribute names

<!-- Before: Non-existent attribute -->
<div aria-role="navigation">...</div>

<!-- After: Correct attribute -->
<div role="navigation">...</div>

3. Fix aria-labelledby

<!-- Before: Hyphenated incorrectly -->
<input aria-labelled-by="name-label">
<label id="name-label">Name</label>

<!-- After: No hyphen between "labelled" and "by" -->
<input aria-labelledby="name-label">
<label id="name-label">Name</label>

4. Replace made-up attributes

These attributes do not exist:

<!-- Before: aria-description doesn't exist -->
<button aria-description="This saves your work">Save</button>

<!-- After: Use aria-describedby with a referenced element -->
<button aria-describedby="save-desc">Save</button>
<span id="save-desc" class="sr-only">This saves your work</span>

Framework examples

Use TypeScript or IDE extensions to catch ARIA typos at build time:
<script setup lang="ts">
// Define labels as typed constants
const buttonLabel = 'Close dialog'
</script>

<template>
  <!-- TypeScript won't catch ARIA typos in templates -->
  <!-- Use eslint-plugin-vuejs-accessibility instead -->
  <button :aria-label="buttonLabel">
    <Icon name="close" />
  </button>
</template>
Add eslint-plugin-vuejs-accessibility to catch these issues during development.

Verify the fix

  1. Re-run Lighthouse accessibility audit
  2. In DevTools Elements panel, confirm attribute names are valid
  3. Test with screen reader:
    • Navigate to the element
    • Confirm the accessible name/description is announced
  4. Use browser accessibility inspector (F12 → Accessibility tab)

Common mistakes

  • Assuming aria-role exists: The attribute is role, not aria-role.
  • Hyphenating labelledby: It's aria-labelledby (one word), not aria-labelled-by.
  • Inventing attributes: Only use attributes defined in the WAI-ARIA specification.
  • Copying code without checking: Stack Overflow answers often contain typos. Verify against MDN or W3C.

Valid ARIA attributes reference

The most commonly used valid attributes:

  • aria-label - Accessible name as a string
  • aria-labelledby - Accessible name from another element's ID
  • aria-describedby - Additional description from another element
  • aria-hidden - Hide from assistive technology
  • aria-expanded - Expandable element state
  • aria-pressed - Toggle button state
  • aria-checked - Checkbox/switch state
  • aria-disabled - Disabled state
  • aria-live - Announce dynamic content changes

Invalid attribute issues often appear alongside:

Test your entire site

ARIA typos hide in component libraries or get copy-pasted across pages. Unlighthouse scans your entire site to find every invalid ARIA attribute, so you can fix typos in one place and make sure accessibility is consistent across all pages.

\n\n\n",[4294,4818,4819,4843,4848,4870,4878,4882,4891,4896,4902,4924,4949,4959],{"__ignoreMap":1843},[4395,4820,4821,4823,4826,4829,4832,4834,4836,4839,4841],{"class":4397,"line":1766},[4395,4822,4407],{"class":4406},[4395,4824,4825],{"class":4410},"script",[4395,4827,4828],{"class":4414}," setup",[4395,4830,4831],{"class":4414}," lang",[4395,4833,4418],{"class":4406},[4395,4835,4422],{"class":4421},[4395,4837,4838],{"class":4425},"ts",[4395,4840,4422],{"class":4421},[4395,4842,4443],{"class":4406},[4395,4844,4845],{"class":4397,"line":1756},[4395,4846,4847],{"class":4400},"// Define labels as typed constants\n",[4395,4849,4850,4854,4858,4862,4865,4867],{"class":4397,"line":1828},[4395,4851,4853],{"class":4852},"swqme","const",[4395,4855,4857],{"class":4856},"smpaK"," buttonLabel",[4395,4859,4861],{"class":4860},"sc1V3"," =",[4395,4863,4864],{"class":4421}," '",[4395,4866,4426],{"class":4425},[4395,4868,4869],{"class":4421},"'\n",[4395,4871,4872,4874,4876],{"class":4397,"line":1749},[4395,4873,4438],{"class":4406},[4395,4875,4825],{"class":4410},[4395,4877,4443],{"class":4406},[4395,4879,4880],{"class":4397,"line":1984},[4395,4881,4449],{"emptyLinePlaceholder":4448},[4395,4883,4884,4886,4889],{"class":4397,"line":4637},[4395,4885,4407],{"class":4406},[4395,4887,4888],{"class":4410},"template",[4395,4890,4443],{"class":4406},[4395,4892,4893],{"class":4397,"line":4657},[4395,4894,4895],{"class":4400}," \n",[4395,4897,4899],{"class":4397,"line":4898},8,[4395,4900,4901],{"class":4400}," \n",[4395,4903,4905,4908,4910,4913,4915,4917,4920,4922],{"class":4397,"line":4904},9,[4395,4906,4907],{"class":4406}," <",[4395,4909,4411],{"class":4410},[4395,4911,4912],{"class":4414}," :aria-label",[4395,4914,4418],{"class":4406},[4395,4916,4422],{"class":4421},[4395,4918,4919],{"class":4425},"buttonLabel",[4395,4921,4422],{"class":4421},[4395,4923,4443],{"class":4406},[4395,4925,4927,4930,4934,4937,4939,4941,4944,4946],{"class":4397,"line":4926},10,[4395,4928,4929],{"class":4406}," <",[4395,4931,4933],{"class":4932},"sFfpx","Icon",[4395,4935,4936],{"class":4414}," name",[4395,4938,4418],{"class":4406},[4395,4940,4422],{"class":4421},[4395,4942,4943],{"class":4425},"close",[4395,4945,4422],{"class":4421},[4395,4947,4948],{"class":4406}," />\n",[4395,4950,4952,4955,4957],{"class":4397,"line":4951},11,[4395,4953,4954],{"class":4406},"