facebook/react · error · Error

DevTools tooltip root node not found: can't display the cont

Error message

DevTools tooltip root node not found: can't display the context menu

What it means

The DevTools context-menu hook portals menus into a container element marked data-react-devtools-portal-root, looked up in the anchor's ownerDocument. When you right-click an element and that node cannot be found, useContextMenu throws instead of rendering a menu at wrong coordinates. The error indicates the DevTools host markup is missing or the anchor lives in a different document than expected.

Source

Thrown at packages/react-devtools-shared/src/devtools/ContextMenu/useContextMenu.js:50

  }, []);

  useEffect(() => {
    const anchor = anchorElementRef.current;
    if (anchor == null) return;

    function handleAnchorContextMenu(e: MouseEvent) {
      e.preventDefault();
      e.stopPropagation();

      const {pageX, pageY} = e;

      const ownerDocument = anchor?.ownerDocument;
      const portalContainer = ownerDocument?.querySelector(
        '[data-react-devtools-portal-root]',
      );

      if (portalContainer == null) {
        throw new Error(
          "DevTools tooltip root node not found: can't display the context menu",
        );
      }

      // `x` and `y` should be relative to the container, to which these context menus will be portaled
      // we can't use just `pageX` or `pageY` for Fusebox integration, because RDT frontend is inlined with the whole document
      // meaning that `pageY` will have an offset of 27, which is the tab bar height
      // for the browser extension, these will equal to 0
      const {top: containerTop, left: containerLeft} =
        portalContainer.getBoundingClientRect();

      setShouldShow(true);
      setPosition({x: pageX - containerLeft, y: pageY - containerTop});
    }

    anchor.addEventListener('contextmenu', handleAnchorContextMenu);
    return () => {
      anchor.removeEventListener('contextmenu', handleAnchorContextMenu);

View on GitHub (pinned to eafeac097b)

Solutions

  1. Ensure the host document contains the portal root: <div data-react-devtools-portal-root="" /> in the document DevTools is mounted into.
  2. If anchors can live in iframes/popups, add the portal root to that same ownerDocument (or re-anchor the UI into the main document).
  3. Upgrade react-devtools-shared to match the frontend markup it expects.

Example fix

// before — host page mounts DevTools without the portal root
<div id="root" />;

// after — provide the node context menus portal into
<div data-react-devtools-portal-root="" />;
<div id="root" />;
Defensive patterns

Strategy: validation

Validate before calling

function ensurePortalRoot(doc) {
  let node = doc.querySelector('[data-react-devtools-portal-root]');
  if (node == null) {
    node = doc.createElement('div');
    node.setAttribute('data-react-devtools-portal-root', '');
    doc.body.appendChild(node);
  }
  return node;
}
ensurePortalRoot(anchor.ownerDocument);

Type guard

function hasPortalRoot(doc) {
  return doc.querySelector('[data-react-devtools-portal-root]') != null;
}

Try / catch

try {
  setShouldShow(true);
} catch (error) {
  if (/DevTools tooltip root node not found/.test(error.message)) return;
  throw error;
}

Prevention

When it happens

Trigger: A contextmenu event fires on an anchored element, and anchor.ownerDocument.querySelector('[data-react-devtools-portal-root]') returns null — e.g. the host page removed/renamed the portal root, or the anchor is inside an iframe/popup whose document never contained it.

Common situations: Embedding the DevTools frontend (Fusebox inlined build, custom integrations) without the expected root markup; anchors rendered into iframes or new windows; CSS/DOM sanitization or SSR hydration dropping unknown empty divs; version skew where markup expectations changed.

Related errors


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