facebook/react · error · Error
Invalid hook call. Hooks can only be called inside of the bo
Error message
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.
What it means
The classic invalid-hook-call error, thrown by the Fizz SSR renderer's resolveCurrentlyRenderingComponent when a hook runs while no component is currently rendering (currentlyRenderingComponent === null). On the server this means the hook executed outside a function component's render pass, or — very commonly — multiple copies of React exist so the hook and the renderer use different dispatcher state.
Source
Thrown at packages/react-server/src/ReactFizzHooks.js:172
(fatalRecoverableError as any).stack = undefined;
}
return fatalRecoverableError;
}
// Lazily created map of render-phase updates
let renderPhaseUpdates: Map<UpdateQueue<any>, Update<any>> | null = null;
// Counter to prevent infinite loops.
let numberOfReRenders: number = 0;
const RE_RENDER_LIMIT = 25;
let isInHookUserCodeInDev = false;
// In DEV, this is the name of the currently executing primitive hook
let currentHookNameInDev: ?string;
function resolveCurrentlyRenderingComponent(): Object {
if (currentlyRenderingComponent === null) {
throw new Error(
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
' one of the following reasons:\n' +
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
'2. You might be breaking the Rules of Hooks\n' +
'3. You might have more than one copy of React in the same app\n' +
'See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.',
);
}
if (__DEV__) {
if (isInHookUserCodeInDev) {
console.error(
'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +
'You can only call Hooks at the top level of your React function. ' +
'For more information, see ' +
'https://react.dev/link/rules-of-hooks',
);
}View on GitHub (pinned to eafeac097b)
Solutions
- Run npm ls react (or yarn why react / pnpm why react) and deduplicate to exactly one copy; use resolutions/overrides if needed
- Ensure react and react-dom are the same version and both come from the same install graph
- Move hooks into function components, called unconditionally at the top level
- Check that libraries you render treat react as an external/peer dependency rather than bundling it
Example fix
// before: hook called at module scope, SSR hits it with no component rendering
const theme = useTheme();
export default function Page() { return <div>{theme}</div>; }
// after
export default function Page() {
const theme = useTheme(); // inside the component render
return <div>{theme}</div>;
}
// package.json — force a single copy if nesting caused duplicates
"resolutions": { "react": "19.0.0", "react-dom": "19.0.0" } Defensive patterns
Strategy: try-catch
Validate before calling
# CI check: fail when more than one react copy exists npm ls react --parseable 2>/dev/null | sort -u | wc -l | grep -q '^1$' || (echo 'duplicate react copies' && exit 1)
Try / catch
const {pipe} = renderToPipeableStream(<App/>, {
onError(err) {
if (String(err.message).includes('Invalid hook call')) {
// Log component stack; check for duplicate React copies and out-of-render hook calls.
logError(err); // render continues for other boundaries
}
},
}); Prevention
- Run npm ls react in CI and fail on duplicate copies; use resolutions/overrides when needed
- Keep react and react-dom at exactly matching versions from a single install
- Only call hooks unconditionally at the top level of function components
- Verify rendered libraries list react as a peerDependency, not a bundled dependency
When it happens
Trigger: Calling useState/useEffect/useMemo or a custom hook from module scope, a plain helper function, a class component, or a callback during server rendering. Rendering with react-dom/server from a different copy than the react package providing hooks (nested node_modules, duplicated installs, a library bundling its own React).
Common situations: Duplicate React installs from npm hoisting issues or monorepos; libraries listing react as a dependency instead of a peerDependency; mixing a CDN/bundled React with an installed one; react-dom version out of sync with react after an upgrade.
Related errors
- Invalid hook call. Hooks can only be called inside of the bo
- 321
- 407
- Rendered more hooks than during the previous render
- Too many re-renders. React limits the number of renders to p
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/c02c1d7debfc8184.
Report an issue: GitHub.