{"record":{"id":"ecfe3537dd7d2b23","repo":"facebook/react","slug":"element-could-not-find-element-at-index-index","errorCode":null,"errorMessage":"<Element> Could not find element at index ${index}","messagePattern":"<Element> Could not find element at index (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/react-devtools-shared/src/devtools/views/Components/Element.js","lineNumber":74,"sourceCode":"          : store.getErrorAndWarningCountForElementID(element.id),\n      subscribe: (callback: Function) => {\n        store.addListener('mutated', callback);\n        return () => store.removeListener('mutated', callback);\n      },\n    }),\n    [store, element],\n  );\n  const {errorCount, warningCount} = useSubscription<{\n    errorCount: number,\n    warningCount: number,\n  }>(errorsAndWarningsSubscription);\n\n  const changeOwnerAction = useChangeOwnerAction();\n  const changeActivitySliceAction = useChangeActivitySliceAction();\n\n  // Handle elements that are removed from the tree while an async render is in progress.\n  if (element == null) {\n    console.warn(`<Element> Could not find element at index ${index}`);\n\n    // This return needs to happen after hooks, since hooks can't be conditional.\n    return null;\n  }\n\n  const handleDoubleClick = () => {\n    startTransition(() => {\n      if (element.type === ElementTypeActivity) {\n        changeActivitySliceAction(element.id);\n      } else {\n        changeOwnerAction(element.id);\n      }\n    });\n  };\n\n  // $FlowFixMe[missing-local-annot]\n  const handleClick = ({metaKey, button}) => {\n    // $FlowFixMe[invalid-compare]","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-devtools-shared/src/devtools/views/Components/Element.js#L56-L92","documentation":"The Element component (packages/react-devtools-shared/src/devtools/views/Components/Element.js) renders one row of the Components tree from a positional index into the Store. It reads the element via a store subscription; when the element at that index is null (it was removed from the tree while an async render was in flight), it warns and returns null after the hooks. The component intentionally keeps hooks unconditional (Rules of Hooks) and bails out — the warning marks a benign race, not a crash.","triggerScenarios":"The store mutates (unmount/filter change) between the parent computing the row index and this component's render committing, so store.getElementAtIndex(index) returns null; common with startTransition-based renders of the virtualized tree while the inspected app updates rapidly.","commonSituations":"Browsing a fast-updating app in the Components tab; toggling filters while a transition render is pending; large trees where virtualization reuses rows across mutations.","solutions":["Treat it as harmless: the row self-heals on the next store mutation render.","If you build custom UI, derive rows by id rather than positional index so removals cannot desync the row.","Ensure your store subscribers re-run on every mutation event so stale rows are replaced promptly."],"exampleFix":"// before (index-based, can desync)\n<Element index={index} ... />\n\n// after (id-based; resolve id first, then render)\nconst id = store.getElementIDAtIndex(index);\n{id !== null && <Element index={index} ... />}","handlingStrategy":"validation","validationCode":"const id = store.getElementIDAtIndex(index);\n// render the row only when the id resolves in the current tree\nreturn id !== null ? <Element index={index} /> : null;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat the warning as a self-healing race; ensure subscribers re-run on store mutation so the row corrects itself.","Prefer id-keyed rows over index-keyed rows in custom tree UIs.","Avoid caching index-based selections across transition renders."],"tags":["react-devtools","components-tree","race-condition","virtualization","dev-only"],"backgroundTag":"stale-element-reference","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}