{"record":{"id":"f3c67e19dfcdcea4","repo":"facebook/react","slug":"can-t-access-root-on-unmounted-test-renderer","errorCode":null,"errorMessage":"Can't access .root on unmounted test renderer","messagePattern":"Can't access \\.root on unmounted test renderer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-test-renderer/src/ReactTestRenderer.js","lineNumber":613,"sourceCode":"      container = null;\n      root = null;\n    },\n    getInstance() {\n      if (root == null || root.current == null) {\n        return null;\n      }\n      return getPublicRootInstance(root);\n    },\n\n    unstable_flushSync: flushSyncFromReconciler,\n  };\n\n  Object.defineProperty(entry, 'root', {\n    configurable: true,\n    enumerable: true,\n    get: function () {\n      if (root === null) {\n        throw new Error(\"Can't access .root on unmounted test renderer\");\n      }\n      const children = getChildren(root.current);\n      if (children.length === 0) {\n        throw new Error(\"Can't access .root on unmounted test renderer\");\n      } else if (children.length === 1) {\n        // Normally, we skip the root and just give you the child.\n        return children[0];\n      } else {\n        // However, we give you the root if there's more than one root child.\n        // We could make this the behavior for all cases but it would be a breaking change.\n        // $FlowFixMe[incompatible-use] found when upgrading Flow\n        return wrapFiber(root.current);\n      }\n    },\n  } as Object);\n\n  return entry;\n}","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-test-renderer/src/ReactTestRenderer.js#L595-L631","documentation":"TestRenderer.root is a getter that throws when the internal root is null, which happens after testRenderer.unmount() has destroyed the root. Once unmounted there is no fiber tree to wrap, so accessing .root is treated as an error rather than returning a stale instance.","triggerScenarios":"Calling testRenderer.unmount() and then reading testRenderer.root in a later assertion or afterEach hook.","commonSituations":"Cleanup code between tests that unmounts but keeps a module-level renderer reference; unmount-then-inspect test patterns that assert on post-unmount state via .root.","solutions":["Capture const root = renderer.root before calling unmount() and use that reference afterwards","Move assertions before unmount(); create a fresh TestRenderer.create(element) for post-unmount checks","Keep unmount() in afterEach but stop touching .root after it runs"],"exampleFix":"// before\nconst renderer = TestRenderer.create(<App />);\nrenderer.unmount();\nconst root = renderer.root; // throws\n\n// after\nconst renderer = TestRenderer.create(<App />);\nconst root = renderer.root; // grab first\nrenderer.unmount();\n// root already captured for any needed assertions","handlingStrategy":"validation","validationCode":"// Capture the root before unmount\nconst renderer = TestRenderer.create(<App />);\nconst root = renderer.root; // safe here\nrenderer.unmount();\n// subsequent code uses `root`, never `renderer.root`","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store renderer.root in a variable immediately after create() and use only that reference","Keep unmount() last in the test; never access .root after cleanup"],"tags":["testing","react-test-renderer","unmounted","root-access"],"backgroundTag":"test-renderer-unmounted-access","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}