oxc-project/oxc · error · OxcDiagnostic

Missing "key" prop for element in array.

Error message

Missing "key" prop for element in array.

What it means

Diagnostic from the oxlint react/jsx-key rule (category: correctness). It fires when a JSX element or fragment appears directly inside an array literal without a 'key' prop. React requires stable keys on elements rendered from arrays so its reconciliation can identify which items changed, were added, or were removed; React itself also emits a console warning at runtime for this. The diagnostic labels the offending element span.

Source

Thrown at crates/oxc_linter/src/rules/react/jsx_key.rs:31

        JSXFragment,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

use crate::{
    AstNode,
    ast_util::is_node_within_call_argument,
    context::{ContextHost, LintContext},
    rule::{DefaultRuleConfig, Rule},
    utils::default_true,
};

const TARGET_METHODS: [&str; 3] = ["flatMap", "from", "map"];

fn missing_key_prop_for_element_in_array(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(r#"Missing "key" prop for element in array."#).with_label(span)
}

fn missing_key_prop_for_element_in_iterator(iter_span: Span, el_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(r#"Missing "key" prop for element in iterator."#)
        .with_help(r#"Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key)."#)
        .with_labels([
            iter_span.label("Iterator starts here."),
            el_span.label("Element generated here."),
        ])
}

fn key_prop_must_be_placed_before_spread(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(r#""key" prop must be placed before any `{...spread}`"#)
        .with_help("To avoid conflicting with React's new JSX transform: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html")
        .with_label(span)
}

fn duplicate_key_prop(key_value: &str, span: Span) -> OxcDiagnostic {

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add a stable, unique key to each element in the array: [<Card key="a"/>, <Card key="b"/>]
  2. Prefer mapping from data so keys derive from items: items.map(x => <Card key={x.id} />)
  3. Ensure keys are stable identifiers (ids), not array index, when the list can reorder
  4. If migrating from ESLint and you truly want the old lax behavior, note oxlint's jsx-key defaults are stricter (all options default true) and can be tuned in .oxlintrc.json

Example fix

// before
const cards = [<Card/>, <Card/>];
return <div>{cards}</div>;

// after
const cards = [<Card key="a"/>, <Card key="b"/>];
return <div>{cards}</div>;
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint -D react/jsx-key src/  # exits non-zero on missing keys; gate CI on it

Prevention

When it happens

Trigger: JSX inside an ArrayExpression element position without a key: const list = [<Card/>, <Card/>]; or [<App/>, ...rest];. (Elements produced inside .map()/.flatMap()/Array.from() callbacks get the sibling 'iterator' diagnostic instead; the rule only runs when the source type is JSX.)

Common situations: Prebuilding arrays of elements outside JSX (e.g. const rows = [<tr/>, <tr/>] then {rows}); mixing spread elements into literal arrays of JSX; converting iterator chains into hand-written arrays during refactor; conditional elements pushed into arrays without keys.

Related errors


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