eslint jsx-a11y no-redundant-roles error
Fixes the jsx-a11y no-redundant-roles error by removing roles that duplicate an element's native semantics. Use it when ESLint flags redundant role attributes. Not for wrong roles, which fail the axe aria-allowed-role rule.
eslint jsx-a11y no-redundant-roles error - how to fix it
TL;DR
Delete the redundant role: role button on a button element, role navigation on a nav element, and friends add nothing. The element's native semantics already do the job. One line of why: redundant roles are harmless today but they rot, the day someone changes the element and forgets the role, the two disagree.
The error, verbatim
/app/src/components/Nav.jsx
4:5 error The element nav has an implicit ARIA role of navigation. Defining this explicitly is redundant jsx-a11y/no-redundant-roles
Fix it step by step
Step 1: Reproduce on one file
npx eslint src/components/Nav.jsx --rule '{"jsx-a11y/no-redundant-roles": "error"}'Expected: ESLint prints the no-redundant-roles error.
Step 2: Find every redundant role
npx eslint src | rg 'no-redundant-roles' | head -20Expected: Full list of elements carrying their own implicit role.
Step 3: Delete the redundant roles
rg -n 'role=.button|role=.navigation|role=.main' src --glob '*.{jsx,tsx,html}' | head -20Expected: Shows the usual suspects to clean up.
Step 4: Re-lint
npx eslint src | rg -c 'no-redundant-roles' || echo 0Expected: Prints 0. Native semantics now do the work with no duplication.
Step 5: Enforce it in CI
npx eslint src --max-warnings 0 | tail -3Expected: Clean output; add the lint command to CI with max-warnings 0 so the violation cannot come back.
When to use this skill
- Your linter output names this exact jsx-a11y / a11y rule
- You want the violation fixed at author time so it never reaches axe or CI
- You are adding the rule to a shared eslint config and need the fix pattern
When NOT to use this skill
- The failure comes from axe-core or lighthouse at runtime, not from lint
- You plan to disable the rule project-wide, this skill shows the fix, not the escape hatch
Compatibility
eslint-plugin-jsx-a11y 6.7+ with eslint 8 or 9. Also flags redundant roles on elements like img (role img) and headings. Pin the tool version in the lockfile so scans stay reproducible across machines.
Variant phrasings
element has implicit aria role defining explicitly is redundant
The default message, same fix.
jsx-a11y redundant role button
The classic: role button on an actual button element.
the rule fires in the editor too
With the eslint extension installed, the same error appears inline while typing; the fix is identical.
Why it happens
Authors add explicit roles defensively (role button on button) or copy them from examples without realizing the element already exposes that role. The rule maps elements to their implicit ARIA semantics and flags exact matches. It is a hygiene rule: redundant roles do not break anything today, but they double the maintenance surface and confuse future readers about intent. Linter rules catch the violation at author time, which is cheaper than any runtime fix. When this rule fires across many files, fix the shared component and mention it in team onboarding so new code does not reintroduce it.
Edge cases
- The rule has an allowRedundantRoles option for teams that want explicit roles as documentation, but deleting is cleaner.
- role presentation on an img IS redundant and flagged, use alt="" on img elements instead.
- Custom elements have no implicit role, so explicit roles on them never trigger this rule.
- After fixing, run the whole lint suite once; a11y rules interact and one fix can surface the next violation.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_vt4yNmonxHhTqdbEnM1V6Q
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.