facebook/react · error · Error
321
321
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': hooks only work while React is rendering a function component, and the reconciler enforces it by swapping in a dispatcher (ContextOnlyDispatcher) whose hook methods throw. The error message itself lists the three root causes it almost always is: mismatched React/renderer versions, breaking the Rules of Hooks, or multiple React copies in one bundle.
Source
Thrown at packages/react-reconciler/src/ReactFiberHooks.js:446
const componentName = getComponentNameFromFiber(currentlyRenderingFiber);
if (!didWarnAboutAsyncClientComponent.has(componentName)) {
didWarnAboutAsyncClientComponent.add(componentName);
console.error(
'%s is an async Client Component. ' +
'Only Server Components can be async at the moment. This error is often caused by accidentally ' +
"adding `'use client'` to a module that was originally written " +
'for the server.',
componentName === null
? 'An unknown Component'
: `<${componentName}>`,
);
}
}
}
}
function throwInvalidHookError() {
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.',
);
}
function areHookInputsEqual(
nextDeps: Array<mixed>,
prevDeps: Array<mixed> | null,
): boolean {
if (__DEV__) {
if (ignorePreviousDependencies) {
// Only true when this component is being hot reloaded.
return false;
}View on GitHub (pinned to eafeac097b)
Solutions
- Run `npm ls react react-dom` (or pnpm why react) and eliminate duplicate copies; add bundler/alias resolution so only one react resolves.
- Align react and react-dom to the exact same version (never mix major/minor).
- Audit the stack trace: ensure every hook call is at the top level of a function component or custom hook — never in conditions, loops, class methods, callbacks, or module scope.
- Install/enable eslint-plugin-react-hooks to catch Rules-of-Hooks violations statically.
Example fix
// before: hook outside a component render
const [count, setCount] = useState(0); // module scope or plain function
// after: hook inside a function component
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
} Defensive patterns
Strategy: validation
Validate before calling
// Boot-time duplicate/copy check: every React global must agree
import React from 'react';
import ReactDOM from 'react-dom';
if (React.version !== ReactDOM.version) {
throw new Error(`react ${React.version} / react-dom ${ReactDOM.version} mismatch`);
}
// plus CI: `npm ls react react-dom` must resolve to exactly one version each Type guard
// Narrow values before calling hook-like helpers: only call hooks inside component render
function isFunctionComponentInProgress() {
// public approximation: hooks must run during render — enforce via eslint rule instead of runtime
return false;
} Try / catch
// Not for swallowing — for diagnosis: capture stack, check for duplicate react in node_modules
window.addEventListener('error', e => {
if (/Invalid hook call/.test(e.message)) console.error(e.error.stack, React.version);
}); Prevention
- npm ls react react-dom in CI; fail on more than one resolved version
- Alias react/react-dom to a single copy in bundler config
- Enable eslint-plugin-react-hooks (rules-of-hooks as error)
- Only call hooks at the top level of function components/custom hooks
When it happens
Trigger: Calling useState/useEffect/... from a class component, a plain function, an event handler body, or outside render entirely; or the hook runs in a component rendered by a different React copy than the one whose hook function you imported (npm dedupe failures, symlinked monorepos, bundler aliasing).
Common situations: Mismatched react/react-dom versions after partial upgrades; two react copies via transitive deps or duplicated peer dependencies in Yarn/pnpm workspaces; calling a custom hook from a non-component function; hooks behind early returns or inside conditions.
Related errors
- react-cache: read and preload may only be called from within
- Could not find helpers for a root. This is a bug in React Re
- Invalid hook call. Hooks can only be called inside of the bo
- Rendered more hooks than during the previous render
- 525
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/99c534794b2405cc.
Report an issue: GitHub.