{"record":{"id":"bdb91478a626058b","repo":"facebook/react","slug":"react-cache-read-and-preload-may-only-be-called-f-bdb914","errorCode":null,"errorMessage":"react-cache: read and preload may only be called from within a component's render. They are not supported in event handlers or lifecycle methods.","messagePattern":"react-cache: read and preload may only be called from within a component's render\\. They are not supported in event handlers or lifecycle methods\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-devtools-shared/src/devtools/cache.js","lineNumber":57,"sourceCode":"  write(Key, Value): void,\n};\n\nlet readContext;\nif (typeof React.use === 'function') {\n  readContext = function (Context: ReactContext<null>) {\n    // eslint-disable-next-line react-hooks-published/rules-of-hooks\n    return React.use(Context);\n  };\n} else if (\n  typeof (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ===\n  'object'\n) {\n  const ReactCurrentDispatcher = (React as any)\n    .__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;\n  readContext = function (Context: ReactContext<null>) {\n    const dispatcher = ReactCurrentDispatcher.current;\n    if (dispatcher === null) {\n      throw new Error(\n        'react-cache: read and preload may only be called from within a ' +\n          \"component's render. They are not supported in event handlers or \" +\n          'lifecycle methods.',\n      );\n    }\n    return dispatcher.readContext(Context);\n  };\n} else {\n  throw new Error('react-cache: Unsupported React version');\n}\n\nconst CacheContext = createContext(null);\n\ntype Config = {useWeakMap?: boolean, ...};\n\nconst entries: Map<\n  Resource<any, any, any>,\n  Map<any, any> | WeakMap<any, any>,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-devtools-shared/src/devtools/cache.js#L39-L75","documentation":"react-devtools-shared vendors a simplified react-cache whose read()/preload() must read the cache context during component render. On React versions without React.use it reaches into __SECRET_INTERNALS ReactCurrentDispatcher; when that dispatcher is null you are outside a render pass (event handler, effect, lifecycle method), so it throws this rules-of-hooks-style error instead of crashing deeper.","triggerScenarios":"Calling resource.read(input) or resource.preload(input) outside of render on a React without React.use — e.g. inside a click handler, useEffect/useLayoutEffect callback, or class lifecycle — so ReactCurrentDispatcher.current is null when readContext runs.","commonSituations":"DevTools frontend (or a fork of its profiling cache) running on React < 19 where the fallback dispatcher path is active; code moved from a component body into an effect or callback during refactor; Suspense-style cache patterns copied into event-driven code.","solutions":["Call read()/preload() during component render only.","If you need the value in an event handler, read it during render and close over the result.","Kick off work with preload() from a render/transition, then read() in a component that suspends."],"exampleFix":"// before\nfunction onClick() {\n  const data = resource.read(id); // dispatcher is null here\n}\n\n// after\nfunction Panel({id}) {\n  const data = resource.read(id); // during render\n  return <pre>{JSON.stringify(data)}</pre>;\n}","handlingStrategy":"type-guard","validationCode":"// only readable during render — check before calling from the React <19 fallback path\nconst dispatcher = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;\nif (dispatcher != null) {\n  dispatcher.readContext(CacheContext);\n}","typeGuard":"function isDuringRender(React) {\n  const internals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n  return internals != null && internals.ReactCurrentDispatcher.current !== null;\n}","tryCatchPattern":"try {\n  value = resource.read(input);\n} catch (error) {\n  if (/may only be called from within a component's render/.test(error.message)) {\n    throw new Error('Moved resource.read() out of render — pass the value from a component instead.');\n  }\n  throw error;\n}","preventionTips":["Treat resource.read/preload like hooks: render-phase only.","Review refactors that move component-body calls into effects or callbacks.","Read during render and close over the result for event handlers."],"tags":["devtools","cache","hooks","rules-of-hooks","render-phase"],"backgroundTag":"invalid-hook-call","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}