{"record":{"id":"3e87c0b48ed7d5b9","repo":"Foundry376/Mailspring","slug":"menu-items-have-colliding-keys","errorCode":null,"errorMessage":"Menu items have colliding keys","messagePattern":"Menu items have colliding keys","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/components/menu.tsx","lineNumber":408,"sourceCode":"      if (React.isValidElement(content) && content.type === MenuItem) {\n        return content;\n      }\n\n      const onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n        event.preventDefault();\n        const key = this.props.itemKey(item);\n        this.setState({ selectedIndex: i, selectedItemKey: key });\n        if (this.props.onSelect) {\n          return this.props.onSelect(item);\n        }\n      };\n\n      const key = this.props.itemKey(item);\n      if (!key) {\n        console.warn('Menu parent did not return an itemKey for item', item);\n      }\n      if (seenItemKeys[key]) {\n        console.warn({ 'Menu items have colliding keys': item }, seenItemKeys[key]);\n      }\n      seenItemKeys[key] = item;\n\n      return (\n        <MenuItem\n          key={key}\n          id={this.props.listboxId ? `${this.props.listboxId}-option-${key}` : undefined}\n          role={this.props.listboxId ? 'option' : undefined}\n          onMouseDown={onMouseDown}\n          checked={this.props.itemChecked && this.props.itemChecked(item)}\n          content={content}\n          selected={this.state.selectedIndex === i}\n          suppressAriaSelected={!!this.props.onActiveDescendantChange}\n        />\n      );\n    });\n\n    const contentClass = classNames({","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/Foundry376/Mailspring/blob/648c685d602ece6bb00c22534b8734de6ac644b3/app/src/components/menu.tsx#L390-L426","documentation":"Warning while rendering Menu items: two items produced the same itemKey, so React reconciliation can swap/duplicate rows and selectedItemKey identifies the wrong item. Duplicate data (e.g. two contacts with the same email rendered as separate rows) is the usual cause.","triggerScenarios":"Thrown at app/src/components/menu.tsx:408 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Deduplicate the items list before rendering","Make itemKey unique by combining fields (id + index or email + label)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"648c685d602ece6bb00c22534b8734de6ac644b3","analyzedAt":"2026-09-03T02:00:24.311Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}