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

  1. Update React DevTools / react-devtools-shared to the matching React build
  2. Reload the page to rebuild backend state if DevTools stops responding after the error
  3. Report with details of SSR streaming setup and which boundaries were unmounted before hydration
  4. 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

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


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