facebook/react · error · Error

Expected the root instance to already exist when starting pr

Error message

Expected the root instance to already exist when starting profiling

What it means

startProfiling() snapshots initial state for every root the hook knows (hook.getFiberRoots(rendererID)) and requires each root to already have a DevTools FiberInstance in rootToFiberInstanceMap - i.e. at least one processed commit (or the initial flush) per root before profiling begins. The throw fires when profiling starts while a known Fiber root was never processed by the backend, so there is no id/tree snapshot to record.

Source

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

  function startProfiling(shouldRecordChangeDescriptions: boolean) {
    if (isProfiling) {
      return;
    }

    recordChangeDescriptions = shouldRecordChangeDescriptions;

    // Capture initial values as of the time profiling starts.
    // It's important we snapshot both the durations and the id-to-root map,
    // since either of these may change during the profiling session
    // (e.g. when a fiber is re-rendered or when a fiber gets removed).
    displayNamesByRootID = new Map();
    initialTreeBaseDurationsMap = new Map();

    hook.getFiberRoots(rendererID).forEach(root => {
      const rootInstance = rootToFiberInstanceMap.get(root);
      if (rootInstance === undefined) {
        throw new Error(
          'Expected the root instance to already exist when starting profiling',
        );
      }
      const rootID = rootInstance.id;
      (displayNamesByRootID as any as DisplayNamesByRootID).set(
        rootID,
        getDisplayNameForRoot(root.current),
      );
      const initialTreeBaseDurations: Array<[number, number]> = [];
      snapshotTreeBaseDurations(rootInstance, initialTreeBaseDurations);
      (initialTreeBaseDurationsMap as any).set(
        rootID,
        initialTreeBaseDurations,
      );
    });

    isProfiling = true;
    profilingStartTime = getCurrentTime();

View on GitHub (pinned to eafeac097b)

Solutions

  1. Let every root render at least once before starting the profiler (interact with the app once, then record).
  2. Avoid 'reload and profile immediately' flows on apps whose roots mount lazily; start recording after load instead.
  3. Keep React and DevTools versions matched and current.
  4. If it persists, file a React issue noting which roots were unrendered when profiling started.
Defensive patterns

Strategy: validation

Validate before calling

// in a custom frontend: only start profiling after at least one commit flush per renderer
if (store.hasReceivedOperations(rendererID)) {
  bridge.send('startProfiling', {recordChangeDescriptions});
}

Try / catch

try {
  bridge.send('startProfiling', {...});
} catch (err) {
  if (err.message.includes('when starting profiling')) {
    // one of the renderer's roots never committed; reload and profile after first render
    console.warn('A root never committed before profiling - reload and retry after render');
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Clicking the Profiler record button (bridge 'startProfiling'), or auto-start (shouldStartProfilingNow at renderer.js:7378, e.g. 'reload and start profiling'), while a root exists that never committed - pre-created createRoot() containers, roots mounted during the same tick profiling starts, or a hook/backend version skew where root registration diverges.

Common situations: Using reload-and-profile on apps with lazily rendered roots; starting a profile immediately after page load before the tree paints; pages with several renderers where one root renders on interaction only.

Related errors


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