facebook/react · error · Error
Unable to acquire scope for the current node. This is a bug
Error message
Unable to acquire scope for the current node. This is a bug in eslint-plugin-react-hooks, please file an issue.
What it means
The react-hooks/exhaustive-deps rule analyzes each hook callback by asking ESLint's ScopeManager for the variable scope of the callback node (scopeManager.acquire(node)). If the scope manager returns null for a node that must have a scope, the rule cannot compute dependencies and aborts with this invariant error. The message itself states it is a bug in eslint-plugin-react-hooks, not a problem in your code. It almost always indicates a mismatch between the AST a parser produced and what the scope manager can map.
Source
Thrown at packages/eslint-plugin-react-hooks/src/rules/ExhaustiveDeps.ts:210
message:
`Effect callbacks are synchronous to prevent race conditions. ` +
`Put the async function inside:\n\n` +
'useEffect(() => {\n' +
' async function fetchData() {\n' +
' // You can await here\n' +
' const response = await MyAPI.getData(someId);\n' +
' // ...\n' +
' }\n' +
' fetchData();\n' +
`}, [someId]); // Or [] if effect doesn't need props or state\n\n` +
'Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching',
});
}
// Get the current scope.
const scope = scopeManager.acquire(node);
if (!scope) {
throw new Error(
'Unable to acquire scope for the current node. This is a bug in eslint-plugin-react-hooks, please file an issue.',
);
}
// Find all our "pure scopes". On every re-render of a component these
// pure scopes may have changes to the variables declared within. So all
// variables used in our reactive hook callback but declared in a pure
// scope need to be listed as dependencies of our reactive hook callback.
//
// According to the rules of React you can't read a mutable value in pure
// scope. We can't enforce this in a lint so we trust that all variables
// declared outside of pure scope are indeed frozen.
const pureScopes = new Set();
let componentScope: Scope.Scope | null = null;
{
let currentScope = scope.upper;
while (currentScope) {
pureScopes.add(currentScope);View on GitHub (pinned to eafeac097b)
Solutions
- Update eslint-plugin-react-hooks to the latest version - several scope-acquisition crashes have been fixed across releases
- Align parser tooling: bump or pin @typescript-eslint/parser and eslint to versions known to work with your plugin version (check the plugin's peer dependencies)
- Shrink the failure to one file/line by linting files individually, then simplify the offending hook until the trigger syntax is obvious
- File an issue on facebook/react with the minimal repro, ESLint config, and package versions - the error message explicitly asks for this
- Unblock CI immediately with /* eslint-disable react-hooks/exhaustive-deps */ on that file, and remove it after the real fix
Example fix
// before (package.json, versions drifted apart) "eslint-plugin-react-hooks": "^4.6.0", "@typescript-eslint/parser": "^8.0.0" // after (upgrade the plugin, keep the toolchain in lockstep) "eslint-plugin-react-hooks": "^5.2.0", "@typescript-eslint/parser": "^8.0.0" // then: npm dedupe && npx eslint --fix-dry-run src/hooks/**
Defensive patterns
Strategy: try-catch
Try / catch
Only relevant when driving ESLint programmatically (editors, lint runners). Catch the Error, match /Unable to acquire scope for the current node/, and treat it as tooling failure: skip the file with a warning instead of failing the entire lint run, then surface the file for an upgrade/report.
Prevention
- Keep eslint-plugin-react-hooks, ESLint core, and your parser (babel/@typescript-eslint) on mutually compatible, pinned versions
- Verify version pins in CI so a transitive upgrade cannot silently introduce the bug
- Lint new or exotic syntax locally before pushing, especially files with hooks
- Watch the plugin changelog when adopting new TypeScript syntax
When it happens
Trigger: Running ESLint with the exhaustive-deps rule when the configured parser (e.g. @typescript-eslint/parser with unusual parserOptions, or an experimental Babel plugin) emits an AST that leaves a hook callback node without an acquireable scope. Also triggered by other ESLint plugins or custom rules that mutate/replace AST nodes before exhaustive-deps visits them, or by plugin versions that predate a fix for a specific syntax pattern.
Common situations: Upgrading eslint-plugin-react-hooks, TypeScript, or @typescript-eslint/* independently so versions drift out of compatibility; monorepos where different packages lint with different parser configs; adopting new syntax (decorators, satisfy expressions, macros) in files containing hooks.
Related errors
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/723d06e9785f4c69.
Report an issue: GitHub.