facebook/react · error · Error
Expected overrideSuspenseMilestone() to not get called for e
Error message
Expected overrideSuspenseMilestone() to not get called for earlier React versions.
What it means
overrideSuspenseMilestone(suspendedSet) is the bulk variant used to force a whole set of Suspense boundaries to a milestone state (suspend all listed, resume the rest). Like the single-boundary override it requires setSuspenseHandler and scheduleUpdate from the renderer; on React versions that predate those DevTools hooks it throws, because there is no API to install the bulk handler.
Source
Thrown at packages/react-devtools-shared/src/backend/fiber/renderer.js:7567
if (!forceFallback && typeof scheduleRetry === 'function') {
// If we're unsuspending and the renderer supports it, use a Retry instead of Sync
// to allow for things like View Transitions to proceed the way they would for real.
scheduleRetry(fiber);
} else {
scheduleUpdate(fiber);
}
}
/**
* Resets the all other roots of this renderer.
* @param suspendedSet List of IDs of SuspenseComponent Fibers
*/
function overrideSuspenseMilestone(suspendedSet: Array<FiberInstance['id']>) {
if (
typeof setSuspenseHandler !== 'function' ||
typeof scheduleUpdate !== 'function'
) {
throw new Error(
'Expected overrideSuspenseMilestone() to not get called for earlier React versions.',
);
}
const unsuspendedSet: Set<Fiber> = new Set(forceFallbackForFibers);
let resuspended = false;
for (let i = 0; i < suspendedSet.length; ++i) {
const instance = idToDevToolsInstanceMap.get(suspendedSet[i]);
if (instance === undefined) {
console.warn(
`Could not suspend ID '${suspendedSet[i]}' since the instance can't be found.`,
);
continue;
}
if (instance.kind === FIBER_INSTANCE) {
const fiber = instance.data;View on GitHub (pinned to eafeac097b)
Solutions
- Upgrade the page's React to a version that injects setSuspenseHandler and scheduleUpdate.
- Before sending the milestone action, verify supportsTogglingSuspense/canToggleSuspense for the renderer and every id in the set.
- Reload the page to re-run capability detection after renderer changes.
- If you maintain a custom frontend, disable milestone controls when the capability check fails instead of sending the message.
Defensive patterns
Strategy: validation
Validate before calling
// before a bulk/milestone suspend, verify the renderer capability once
const renderer = hook.renderers.get(rendererID);
const canMilestone =
typeof renderer?.setSuspenseHandler === 'function' &&
typeof renderer?.scheduleUpdate === 'function';
if (canMilestone) {
bridge.send('overrideSuspenseMilestone', {ids, rendererID});
} Prevention
- Hide milestone/bulk-suspend controls when setSuspenseHandler or scheduleUpdate is missing from the renderer.
- Re-check capabilities after any renderer swap (HMR) before issuing bulk operations.
- Keep React and DevTools versions aligned.
When it happens
Trigger: A bulk suspend/unsuspend action (milestone navigation in the profiler/components UI, or a custom frontend sending the corresponding bridge message with an ID array) while the attached renderer is older than the version that introduced setSuspenseHandler/scheduleUpdate.
Common situations: Newer DevTools frontend driving an older pinned React renderer; embedding devtools-shared and wiring milestone controls without capability checks; renderers swapped by HMR.
Related errors
- Expected overrideSuspense() to not get called for earlier Re
- Expected overrideError() to not get called for earlier React
- The should not be any remaining suspense node children if th
- There should always be an Offscreen Fiber child in a hydrate
- A dehydrated Suspense node should not have a content Fiber.
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/28b444ed879a33b6.
Report an issue: GitHub.