facebook/react · error · Error
A dehydrated Suspense node should not have a content Fiber.
Error message
A dehydrated Suspense node should not have a content Fiber.
What it means
Companion invariant to the previous unmount check, on the dehydrated branch: a Suspense boundary that isFiberHydrated reports false must not have any remaining content fiber instances. The backend treats dehydrated boundaries as childless until hydration, so leftover content instances indicate corrupted reconciliation state or a tree shape the backend does not understand.
Source
Thrown at packages/react-devtools-shared/src/backend/fiber/renderer.js:3653
const hydrated = isFiberHydrated(fiber);
if (hydrated) {
if (contentFiberInstance === null) {
throw new Error(
'There should always be an Offscreen Fiber child in a hydrated Suspense boundary.',
);
}
unmountSuspenseChildrenRecursively(
contentFiberInstance,
stashedSuspenseParent,
stashedSuspensePrevious,
stashedSuspenseRemaining,
);
// unmountSuspenseChildren already popped
shouldPopSuspenseNode = false;
} else {
if (contentFiberInstance !== null) {
throw new Error(
'A dehydrated Suspense node should not have a content Fiber.',
);
}
}
} else {
unmountRemainingChildren();
}
removePreviousSuspendedBy(
instance,
previousSuspendedBy,
reconcilingParentSuspenseNode,
);
} finally {
reconcilingParent = stashedParent;
previouslyReconciledSibling = stashedPrevious;
remainingReconcilingChildren = stashedRemaining;
if (shouldPopSuspenseNode) {
reconcilingParentSuspenseNode = stashedSuspenseParent;View on GitHub (pinned to eafeac097b)
Solutions
- Update React DevTools / react-devtools-shared to the matching React build
- Reload the page to rebuild backend state if DevTools stops responding after the error
- Report with details of SSR streaming setup and which boundaries were unmounted before hydration
- If embedding, catch invariant errors from the commit hook and rebuild the mirror from scratch as recovery
Defensive patterns
Strategy: try-catch
Try / catch
try {
backend.handleCommitFiberRoot(renderer, root);
} catch (e) {
if (/dehydrated Suspense node should not have a content Fiber/.test(e.message)) {
scheduleBackendReset(); // hydration state bookkeeping diverged
} else throw e;
} Prevention
- Match renderer and DevTools builds; dehydration/hydration flag semantics changed across releases
- Let unmounted streaming boundaries be cleaned up before deep inspection
- Report interleavings of unmount commits with hydration completion
- Reset backend state on first invariant error to avoid cascades
When it happens
Trigger: Unmounting a Suspense boundary that is still dehydrated but somehow has mirrored content instances under it; hydration state flapping between commits; renderer/DevTools disagreement about memoizedState / hydration flags.
Common situations: Streaming SSR with boundaries that never hydrated before unmount; canary React hydration changes with an older DevTools backend; race between unmount commits and backend traversal.
Related errors
- There should always be an Offscreen Fiber child in a hydrate
- Encountered a dehydrated Suspense boundary that was previous
- The should not be any remaining suspense node children if th
- Attempted to measure a Suspense node that does not exist.
- There should always be a SuspenseNode parent on a mounted in
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/ac8ed736ad377b63.
Report an issue: GitHub.