oxc-project/oxc · warning
The `{element}` element has an implicit role of `{role}`. De
Error message
The `{element}` element has an implicit role of `{role}`. Defining this explicitly is redundant and should be avoided. What it means
This is the `jsx_a11y/no-redundant-roles` rule in oxlint. It fires when an element's explicit `role` prop duplicates an implicit role that the element already has (computed via `get_element_implicit_roles`), e.g. `<button role="button">`. The redundancy adds noise and can confuse tooling; the only default exception is `nav` -> `navigation` (see `DEFAULT_ROLE_EXCEPTIONS`), allowed unless removed via `allowedRedundantRoles` config.
Source
Thrown at crates/oxc_linter/src/rules/jsx_a11y/no_redundant_roles.rs:25
ast::{Expression, JSXAttributeItem, JSXAttributeValue, JSXOpeningElement},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_str::CompactStr;
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
utils::{
get_element_implicit_roles, get_element_type, get_prop_value,
get_string_literal_prop_value, has_jsx_prop_ignore_case, parse_jsx_value,
},
};
fn no_redundant_roles_diagnostic(span: Span, element: &str, role: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"The `{element}` element has an implicit role of `{role}`. Defining this explicitly is redundant and should be avoided."
))
.with_help(format!("Remove the redundant role `{role}` from the element `{element}`."))
.with_label(span)
}
/// Redundant roles that are allowed by default unless overridden by the
/// `allowedRedundantRoles` option, mirroring eslint-plugin-jsx-a11y's
/// `DEFAULT_ROLE_EXCEPTIONS`.
const DEFAULT_ROLE_EXCEPTIONS: &[(&str, &str)] = &[("nav", "navigation")];
#[derive(Debug, Clone, Default, Deserialize)]
pub struct NoRedundantRoles(Box<NoRedundantRolesConfig>);
#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]
pub struct NoRedundantRolesConfig {
/// A mapping of element names to the redundant roles that are explicitly
/// allowed on them. Providing an entry overrides the default exceptions forView on GitHub (pinned to e1e7af627c)
Solutions
- Delete the redundant `role` attribute and rely on the element's implicit semantics.
- If you intentionally want the redundancy documented (like `nav role="navigation"`), confirm it is in `allowedRedundantRoles`.
- Audit for other copy-pasted roles in the same file.
Example fix
// before
<button role="button" onClick={fn}>Save</button>
// after
<button onClick={fn}>Save</button> Defensive patterns
Strategy: validation
Validate before calling
npx oxlint --jsx-a11y/no-redundant-roles src/
Prevention
- Trust implicit semantics; do not restate roles the tag already has.
- During code review, delete role attributes that duplicate the element name.
- Maintain allowedRedundantRoles only for documented exceptions like nav/navigation.
When it happens
Trigger: A JSX element with a literal `role` string that equals one of its implicit ARIA roles and is not whitelisted by `DEFAULT_ROLE_EXCEPTIONS` or the rule's `allowedRedundantRoles` option.
Common situations: Developers adding roles 'to be explicit' on `<button>`, `<nav>`, `<main>`, `<header>`; code migrated from strict-ARIA codebases; template snippets that pre-fill roles; refactors that changed tags without dropping their old role attributes.
Related errors
- Interactive elements should not be assigned non-interactive
- Non-interactive elements should not be assigned interactive
- Static HTML elements with event handlers require a role.
- Prefer `{tag}` over `role` attribute `{role}`.
- The attribute `{attr_name}` is not supported by the role `{r
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/e8a7c50896f11b85.
Report an issue: GitHub.