{"record":{"id":"a04efca4289df645","repo":"facebook/react","slug":"encountered-a-dehydrated-suspense-boundary-that-wa","errorCode":null,"errorMessage":"Encountered a dehydrated Suspense boundary that was previously hydrated.","messagePattern":"Encountered a dehydrated Suspense boundary that was previously hydrated\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-devtools-shared/src/backend/fiber/renderer.js","lineNumber":4720,"sourceCode":"              'There should always be an Offscreen Fiber child in a hydrated Suspense boundary.',\n            );\n          }\n\n          trackThrownPromisesFromRetryCache(suspenseNode, nextFiber.stateNode);\n          // Toggle suspended state.\n          recordSuspenseSuspenders(suspenseNode);\n\n          mountSuspenseChildrenRecursively(\n            nextContentFiber,\n            traceNearestHostComponentUpdate,\n            stashedSuspenseParent,\n            stashedSuspensePrevious,\n            stashedSuspenseRemaining,\n          );\n          // mountSuspenseChildrenRecursively popped already\n          shouldPopSuspenseNode = false;\n        } else if (previousHydrated && !nextHydrated) {\n          throw new Error(\n            'Encountered a dehydrated Suspense boundary that was previously hydrated.',\n          );\n        } else {\n          // This Suspense Fiber is still dehydrated. It won't have any children\n          // until hydration.\n        }\n      } else {\n        // Common case: Primary -> Primary.\n        // This is the same code path as for non-Suspense fibers.\n        if (nextFiber.child !== prevFiber.child) {\n          updateFlags |= updateChildrenRecursively(\n            nextFiber.child,\n            prevFiber.child,\n            traceNearestHostComponentUpdate,\n          );\n        } else {\n          // Children are unchanged.\n          if (fiberInstance !== null) {","sourceCodeStart":4702,"sourceCodeEnd":4738,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-devtools-shared/src/backend/fiber/renderer.js#L4702-L4738","documentation":"One-way hydration invariant on the update path: the backend asserts a Suspense boundary never goes from hydrated back to dehydrated between two observed fibers. React treats dehydration as terminal per boundary instance, so this transition implies the backend compared mismatched fiber instances or observed commits out of order - i.e. corrupted mirror state or a version-skew bug.","triggerScenarios":"The prev fiber reports hydrated and the next fiber of the 'same' boundary reports dehydrated; typically after earlier swallowed errors desynchronized fiberInstance/fiber pairing, or renderer behavior changes (Activity remounting boundaries) the backend does not model.","commonSituations":"Long DevTools sessions after a prior invariant failure; canary React changing Suspense remount semantics; duplicated React copies producing alternate fiber identities.","solutions":["Reload the inspected app to reset the DevTools backend mirror completely","Update React DevTools and React to matching versions/channels","Verify the app does not load two React copies (npm ls react)","Report with the DevTools console output and steps if it recurs on clean matching versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  backend.handleCommitFiberRoot(renderer, root);\n} catch (e) {\n  if (/dehydrated Suspense boundary that was previously hydrated/.test(e.message)) {\n    fullMirrorRebuild(root); // pairing corrupted; rebuild from scratch\n  } else throw e;\n}","preventionTips":["Reload the inspected app after any DevTools invariant - this throw is usually a downstream symptom of desynced state","Match React/DevTools versions; boundary remount semantics (Activity) evolved","Check for duplicate React copies (npm ls react) that create alternate fiber identities","Report paired errors (first invariant + this one) together"],"tags":["react-devtools","invariant","suspense","hydration","state-corruption","internal"],"backgroundTag":"suspense-boundary-invariant-violation","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}