{"record":{"id":"bf86cb2d33a2427a","repo":"oxc-project/oxc","slug":"missing-key-prop-for-element-in-iterator","errorCode":null,"errorMessage":"Missing \"key\" prop for element in iterator.","messagePattern":"Missing \"key\" prop for element in iterator\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/react/jsx_key.rs","lineNumber":35,"sourceCode":"use 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 {\n    OxcDiagnostic::warn(format!(\"Duplicate key '{key_value}' found in JSX elements\"))\n        .with_help(\"Each child in a list should have a unique 'key' prop\")\n        .with_label(span)\n}","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/react/jsx_key.rs#L17-L53","documentation":"The iterator variant of react/jsx-key: a JSX element is produced inside an iterator callback without a 'key' prop. The rule detects calls whose callee name is one of TARGET_METHODS = [\"flatMap\", \"from\", \"map\"] (plus React.Children.toArray) and reports elements returned from their callbacks. It carries two labels — 'Iterator starts here.' on the iterator span and 'Element generated here.' on the element — plus a help link to the React docs on keeping list items in order with key.","triggerScenarios":"items.map(x => <Row/>) or items.flatMap(x => [<Row/>, <Divider/>]) or Array.from(items, x => <Row x={x}/>) where the produced element lacks a key prop; also elements nested inside those callbacks (e.g. wrapped in unnecessary parens or conditionals) without keys.","commonSituations":"Rendering lists in components; refactoring for-loops into .map chains; forgetting keys when the callback body is a conditional or fragment; nested maps producing keyed outer elements but unkeyed inner ones.","solutions":["Add key={...} with a unique stable value to the element returned by the callback: items.map(x => <Row key={x.id}/>)","Use the item's stable id rather than the array index when order can change","When a fragment groups multiple elements per iteration, put the key on the <Fragment key={...}> shorthand, not on children","Keep every element generated by the iteration keyed, including elements inside conditionals within the callback"],"exampleFix":"// before\n{items.map(x => <Row data={x}/>)}\n\n// after\n{items.map(x => <Row key={x.id} data={x}/>)}","handlingStrategy":"validation","validationCode":"npx oxlint -D react/jsx-key src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always key the element returned from map/flatMap/Array.from callbacks using a stable id","When grouping per-iteration output, put the key on <Fragment key={...}> rather than children","Watch the React devtools 'missing key' console warning in development as an early signal"],"tags":["react","jsx","list-key","iterator","map","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"}