facebook/react · warning

<Element> Could not find element at index ${index}

Error message

<Element> Could not find element at index ${index}

What it means

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.

Source

Thrown at packages/react-devtools-shared/src/devtools/views/Components/Element.js:74

          : store.getErrorAndWarningCountForElementID(element.id),
      subscribe: (callback: Function) => {
        store.addListener('mutated', callback);
        return () => store.removeListener('mutated', callback);
      },
    }),
    [store, element],
  );
  const {errorCount, warningCount} = useSubscription<{
    errorCount: number,
    warningCount: number,
  }>(errorsAndWarningsSubscription);

  const changeOwnerAction = useChangeOwnerAction();
  const changeActivitySliceAction = useChangeActivitySliceAction();

  // Handle elements that are removed from the tree while an async render is in progress.
  if (element == null) {
    console.warn(`<Element> Could not find element at index ${index}`);

    // This return needs to happen after hooks, since hooks can't be conditional.
    return null;
  }

  const handleDoubleClick = () => {
    startTransition(() => {
      if (element.type === ElementTypeActivity) {
        changeActivitySliceAction(element.id);
      } else {
        changeOwnerAction(element.id);
      }
    });
  };

  // $FlowFixMe[missing-local-annot]
  const handleClick = ({metaKey, button}) => {
    // $FlowFixMe[invalid-compare]

View on GitHub (pinned to eafeac097b)

Solutions

  1. Treat it as harmless: the row self-heals on the next store mutation render.
  2. If you build custom UI, derive rows by id rather than positional index so removals cannot desync the row.
  3. Ensure your store subscribers re-run on every mutation event so stale rows are replaced promptly.

Example fix

// before (index-based, can desync)
<Element index={index} ... />

// after (id-based; resolve id first, then render)
const id = store.getElementIDAtIndex(index);
{id !== null && <Element index={index} ... />}
Defensive patterns

Strategy: validation

Validate before calling

const id = store.getElementIDAtIndex(index);
// render the row only when the id resolves in the current tree
return id !== null ? <Element index={index} /> : null;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/ecfe3537dd7d2b23. Report an issue: GitHub.