facebook/react · error · Error

Expected a root instance to exist for this Fiber root

Error message

Expected a root instance to exist for this Fiber root

What it means

inspectRootsRaw() merges per-root inspection data by looking up every Fiber root the hook knows (hook.getFiberRoots(rendererID)) in rootToFiberInstanceMap. That map is only written when the backend processes a root: the initial tree flush on connect (flushInitialOperations, renderer.js:4978), every commit (handleCommitFiberRoot, renderer.js:5054), and filter re-mounts (renderer.js:980). The throw means a Fiber root exists that the backend never mounted or tracked - a violation of the backend's own ordering invariant, not of user code.

Source

Thrown at packages/react-devtools-shared/src/backend/fiber/renderer.js:6892

      canEditHooksAndDeletePaths: false,
      canEditHooksAndRenamePaths: false,
      canToggleError: false,
      canToggleSuspense: false,
      isSuspended: false,
      hasLegacyContext: false,
      context: null,
      hooks: null,
      props: null,
      state: null,
      owners: null,
    };

    let minSuspendedByRange = Infinity;
    let maxSuspendedByRange = -Infinity;
    roots.forEach(root => {
      const rootInstance = rootToFiberInstanceMap.get(root);
      if (rootInstance === undefined) {
        throw new Error(
          'Expected a root instance to exist for this Fiber root',
        );
      }
      const inspectedRoot = inspectFiberInstanceRaw(rootInstance);
      if (inspectedRoot === null) {
        return;
      }

      if (inspectedRoot.isErrored) {
        inspectedRoots.isErrored = true;
      }
      for (let i = 0; i < inspectedRoot.errors.length; i++) {
        inspectedRoots.errors.push(inspectedRoot.errors[i]);
      }
      for (let i = 0; i < inspectedRoot.warnings.length; i++) {
        inspectedRoots.warnings.push(inspectedRoot.warnings[i]);
      }
      for (let i = 0; i < inspectedRoot.suspendedBy.length; i++) {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Reload the page with DevTools already open so the backend observes every root from creation through its first commit.
  2. Make sure every createRoot() container actually gets an initial render before you inspect elements in it.
  3. Upgrade React and the DevTools extension together - fixes for root-tracking races land in both.
  4. If reproducible on current versions, file a React issue with the multi-root setup and timing.
Defensive patterns

Strategy: validation

Validate before calling

// in a custom integration: only inspect ids the backend has actually reported
const knownRoot = store.getRootsForRenderer(rendererID).find(r => r.id === id);
if (knownRoot != null && knownRoot.hasCommitted !== false) {
  bridge.send('inspectElement', {id, rendererID});
}

Try / catch

try {
  bridge.send('inspectElement', {id, rendererID});
} catch (err) {
  if (err.message.includes('Expected a root instance to exist')) {
    // backend root tracking diverged from the hook; only a reload resyncs it
    console.warn('DevTools root tracking out of sync - reload the page with DevTools open');
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Inspecting a root element (an instance with parent === null, or any action that calls inspectRootsRaw) in a multi-root app while some root in getFiberRoots has never committed - e.g. createRoot() containers that have not rendered yet, roots created during a filter re-mount window, or DevTools attaching mid-session after roots were registered with the hook but before their first processed commit.

Common situations: Apps that pre-create roots (createRoot) lazily and render later; hot reload remounting roots while DevTools re-initializes; reload-and-inspect flows racing the initial 'operations' flush; multi-renderer pages where one renderer has not flushed yet.

Related errors


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