oxc-project/oxc · warning

Non-interactive elements should not be assigned mouse or key

Error message

Non-interactive elements should not be assigned mouse or keyboard event listeners.

What it means

This is the `jsx_a11y/no-noninteractive-element-interactions` rule in oxlint. It fires when a non-interactive HTML element (per `is_non_interactive_element`, e.g. `<li>`, `<td>`, `<h1>`) is assigned a mouse or keyboard event handler such as `onClick` or `onKeyDown`. Screen-reader users get no affordance that the element is operable, so handlers belong on interactive elements.

Source

Thrown at crates/oxc_linter/src/rules/jsx_a11y/no_noninteractive_element_interactions.rs:29

use oxc_str::CompactStr;
use rustc_hash::FxHashMap;
use schemars::JsonSchema;
use serde::Deserialize;

use crate::{
    AstNode,
    context::LintContext,
    globals::HTML_TAG,
    rule::{DefaultRuleConfig, Rule},
    utils::{
        get_element_type, get_prop_value, get_string_literal_prop_value, has_jsx_prop,
        has_jsx_prop_ignore_case, is_hidden_from_screen_reader, is_interactive_element,
        is_interactive_role, is_non_interactive_element, is_non_interactive_role, parse_jsx_value,
    },
};

fn no_noninteractive_element_interactions_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "Non-interactive elements should not be assigned mouse or keyboard event listeners.",
    )
    .with_help(
        "Move the handler to an interactive element, or use an appropriate interactive role.",
    )
    .with_label(span)
}

const RECOMMENDED_HANDLERS: &[&str] = &[
    // image
    "onError",
    "onLoad",
    // keyboard
    "onKeyPress",
    "onKeyDown",
    "onKeyUp",
    // focus
    "onFocus",

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Move the handler to a real interactive element such as `<button>` inside the non-interactive one.
  2. Give the element an interactive role plus `tabIndex` and keyboard handlers (e.g. `role="button" tabIndex={0} onKeyDown={...}`).
  3. Add the specific handler name to the rule's `handlers` config if it is intentionally non-pointer (like `onMouseOver`).

Example fix

// before
<li onClick={() => select(item)}>{item.name}</li>

// after
<li><button onClick={() => select(item)}>{item.name}</button></li>
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --jsx-a11y/no-noninteractive-element-interactions src/

Prevention

When it happens

Trigger: A non-interactive HTML element carries a handler prop (via `get_prop_value`) that is not in the allowed `RECOMMENDED_HANDLERS` list (which permits things like `onError`/`onLoad` on images), the element is not hidden from screen readers, has no interactive role, and the pairing is not exempted by the rule's `handlers`/role config.

Common situations: `<li onClick>` in hand-rolled menus and listboxes; `<td onClick>` in clickable table rows; `<h2 onClick>` acting as a disclosure toggle; components built before the team adopted jsx-a11y.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/d6ce13c3ec678e2c. Report an issue: GitHub.