facebook/react · error · Error
Unsupported node type: ${node.type}
Error message
Unsupported node type: ${node.type} What it means
This is the catch-all of analyzePropertyChain in exhaustive-deps. The function only knows how to turn Identifiers and non-computed MemberExpression/OptionalMemberExpression chains into dotted paths; any other node type - computed member access, calls, binary expressions, template literals - cannot become a property chain and hits the final throw with the node's type name. So a dependency entry whose root shape is not a plain dotted reference crashes the rule.
Source
Thrown at packages/eslint-plugin-react-hooks/src/rules/ExhaustiveDeps.ts:1966
markNode(node, optionalChains, result);
return result;
} else if (
node.type === 'ChainExpression' &&
(!('computed' in node) || !node.computed)
) {
const expression = node.expression;
if (expression.type === 'CallExpression') {
throw new Error(`Unsupported node type: ${expression.type}`);
}
const object = analyzePropertyChain(expression.object, optionalChains);
const property = analyzePropertyChain(expression.property, null);
const result = `${object}.${property}`;
markNode(expression, optionalChains, result);
return result;
} else {
throw new Error(`Unsupported node type: ${node.type}`);
}
}
function getNodeWithoutReactNamespace(
node: Expression | Super,
): Expression | Identifier | Super {
if (
node.type === 'MemberExpression' &&
node.object.type === 'Identifier' &&
node.object.name === 'React' &&
node.property.type === 'Identifier' &&
!node.computed
) {
return node.property;
}
return node;
}
View on GitHub (pinned to eafeac097b)
Solutions
- Replace the offending entry with a reference the rule understands: depend on the array/object (items) or the function (fn), not an indexed or called result
- Hoist the computed value into a stable variable (const first = items[0]) before the hook and depend on the variable
- Update eslint-plugin-react-hooks in case your version predates support for the syntax shape you hit
- If the exotic dependency is intentional, inline eslint-disable-next-line react-hooks/exhaustive-deps with a justification comment
Example fix
// before useMemo(() => items[0]?.trim(), [items[0]]); // after const first = items[0]; useMemo(() => first?.trim(), [first]);
Defensive patterns
Strategy: validation
Validate before calling
// Flag non-reference deps entries (computed access, calls, expressions)
// before lint: hook callbacks and their arrays can be checked with a quick parse
// (or simply review for these shapes): items[i], data[key], fn(), a + b
const suspiciousDep = /\[\s*(\w+\s*\[|\w+\s*\(|[^\]a-zA-Z0-9._$\s])/;
if (suspiciousDep.test(depsArraySource)) {
console.warn('Deps array contains a computed/call/expression entry - hoist it to a variable');
} Prevention
- Deps arrays should contain references (identifiers and dotted chains), not expressions
- Hoist computed values (items[0], data[key]) into named variables before the hook
- Depend on the function itself, never on its call
- Code-review dependency arrays in hook-heavy modules
When it happens
Trigger: A dependency array entry that is a computed access (items[i], data[key]), a direct invocation (fn() or obj.method()), or an arbitrary expression (a + b, `tpl-${x}`) where analyzePropertyChain is asked to analyze the root node. Computed MemberExpression (node.computed === true) and bare CallExpression both fall through every accepting branch into the else-throw.
Common situations: Listing a computed value like items[0] as a dependency instead of items; listing a function call result instead of the function; migrating codebases where deps arrays were written casually; older plugin versions paired with newer parsers.
Related errors
- Unsupported node type: ${expression.type}
- Unable to acquire scope for the current node. This is a bug
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/a38f2718d7a7fd99.
Report an issue: GitHub.