{"record":{"id":"07254ac001bb9c54","repo":"oxc-project/oxc","slug":"missing-key-prop-for-element-in-array","errorCode":null,"errorMessage":"Missing \"key\" prop for element in array.","messagePattern":"Missing \"key\" prop for element in array\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/react/jsx_key.rs","lineNumber":31,"sourceCode":"        JSXFragment,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    AstNode,\n    ast_util::is_node_within_call_argument,\n    context::{ContextHost, LintContext},\n    rule::{DefaultRuleConfig, Rule},\n    utils::default_true,\n};\n\nconst TARGET_METHODS: [&str; 3] = [\"flatMap\", \"from\", \"map\"];\n\nfn missing_key_prop_for_element_in_array(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(r#\"Missing \"key\" prop for element in array.\"#).with_label(span)\n}\n\nfn missing_key_prop_for_element_in_iterator(iter_span: Span, el_span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(r#\"Missing \"key\" prop for element in iterator.\"#)\n        .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).\"#)\n        .with_labels([\n            iter_span.label(\"Iterator starts here.\"),\n            el_span.label(\"Element generated here.\"),\n        ])\n}\n\nfn key_prop_must_be_placed_before_spread(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(r#\"\"key\" prop must be placed before any `{...spread}`\"#)\n        .with_help(\"To avoid conflicting with React's new JSX transform: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html\")\n        .with_label(span)\n}\n\nfn duplicate_key_prop(key_value: &str, span: Span) -> OxcDiagnostic {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/react/jsx_key.rs#L13-L49","documentation":"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.","triggerScenarios":"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.)","commonSituations":"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.","solutions":["Add a stable, unique key to each element in the array: [<Card key=\"a\"/>, <Card key=\"b\"/>]","Prefer mapping from data so keys derive from items: items.map(x => <Card key={x.id} />)","Ensure keys are stable identifiers (ids), not array index, when the list can reorder","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"],"exampleFix":"// before\nconst cards = [<Card/>, <Card/>];\nreturn <div>{cards}</div>;\n\n// after\nconst cards = [<Card key=\"a\"/>, <Card key=\"b\"/>];\nreturn <div>{cards}</div>;","handlingStrategy":"validation","validationCode":"npx oxlint -D react/jsx-key src/  # exits non-zero on missing keys; gate CI on it","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat key as mandatory on every element in an array literal; make it a code-review checklist item","Prefer data.map(item => <Row key={item.id}/>) over hand-built element arrays","Enable react/jsx-key (it is in the correctness category) in the default config so it cannot be skipped"],"tags":["react","jsx","list-key","reconciliation","oxlint","lint"],"backgroundTag":"react-missing-list-key","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}