facebook/react · error · Error
Unknown Fiber. Needs to be a function component to inspect h
Error message
Unknown Fiber. Needs to be a function component to inspect hooks.
What it means
inspectHooksOfFiber (via inspectHooksOfFiberImpl in react-debug-tools) only accepts fibers whose tag is FunctionComponent, SimpleMemoComponent, or ForwardRef, because hooks can only live on function components. Passing any other fiber tag (class components, host elements, MemoComponent, Suspense, etc.) throws immediately before any hook is read.
Source
Thrown at packages/react-debug-tools/src/ReactDebugHooks.js:1347
}
return props;
}
return baseProps;
}
// Shared implementation. Requires an explicit dispatcher and never references
// ReactSharedInternals (it delegates to inspectHooksImpl), so importing it does
// not pull React into the bundle.
function inspectHooksOfFiberImpl(
fiber: Fiber,
currentDispatcher: CurrentDispatcherRef,
): HooksTree {
if (
fiber.tag !== FunctionComponent &&
fiber.tag !== SimpleMemoComponent &&
fiber.tag !== ForwardRef
) {
throw new Error(
'Unknown Fiber. Needs to be a function component to inspect hooks.',
);
}
// Warm up the cache so that it doesn't consume the currentHook.
getPrimitiveStackCache();
// Set up the current hook so that we can step through and read the
// current state from them.
currentHook = fiber.memoizedState as Hook;
currentFiber = fiber;
const thenableState =
fiber.dependencies && fiber.dependencies._debugThenableState;
// In DEV the thenableState is an inner object.
const usedThenables: any = thenableState
? thenableState.thenables || thenableState
: null;
currentThenableState = Array.isArray(usedThenables) ? usedThenables : null;View on GitHub (pinned to eafeac097b)
Solutions
- Guard fiber.tag before calling: only FunctionComponent, SimpleMemoComponent, and ForwardRef are inspectable
- If you have a MemoComponent fiber, step into the inner function component it wraps and inspect that component's fiber during its render
- For class components there are no hooks to inspect - use the fiber's stateNode and memoizedState directly instead
- Use the exported inspectHooks(renderFunction, props) form when you have the component function itself rather than a fiber
Example fix
// before
inspectHooksOfFiber(fiber); // throws for class/host/memo fibers
// after
const INSPECTABLE = new Set(['FunctionComponent', 'SimpleMemoComponent', 'ForwardRef']);
if (INSPECTABLE.has(fiber.type? fiber.type.name : '') || [0, 11, 15].includes(fiber.tag)) {
inspectHooksOfFiber(fiber);
} Defensive patterns
Strategy: type-guard
Validate before calling
// before inspecting, confirm the fiber is a hooks-capable function component
import {FunctionComponent, SimpleMemoComponent, ForwardRef} from 'react-reconciler/src/ReactWorkTags';
if (fiber.tag !== FunctionComponent && fiber.tag !== SimpleMemoComponent && fiber.tag !== ForwardRef) {
skipInspection(fiber); // class/host/memo fibers have no inspectable hooks
} Type guard
function canInspectHooks(fiber: Fiber): boolean {
return (
fiber.tag === FunctionComponent || // 0
fiber.tag === SimpleMemoComponent || // 15
fiber.tag === ForwardRef // 11
);
} Try / catch
try {
return inspectHooksOfFiber(fiber, currentDispatcher);
} catch (e) {
if (e.message.includes('Needs to be a function component to inspect hooks')) {
return []; // not a hooks component; nothing to inspect
}
throw e;
} Prevention
- Derive fibers from the component's own render path (owner fibers), not by walking up from arbitrary DOM stateNodes
- Treat memo(fn) fibers (MemoComponent tag) as wrappers - resolve to the inner function component first
- Check fiber.tag against the three allowed tags before every inspectHooksOfFiber call
- Prefer inspectHooks(renderFunction, props) when you already hold the component function
When it happens
Trigger: Calling inspectHooksOfFiber with a fiber grabbed from a DOM node via the internal instance key without walking up to the owning function component; passing a class component's fiber; passing a memo(fn) fiber (tag MemoComponent, which is not the same as SimpleMemoComponent); passing a host component or Suspense fiber.
Common situations: Building custom DevTools-like tooling or codemods that traverse fibers; walking up from stateNode and stopping at the wrong fiber; inspecting memo/forwardRef/class wrappers whose fiber tag differs from the inner function component.
Related errors
- An unsupported type was passed to use(): ${String(usable)}
- Unexpected dehydrated hook; this is a DevTools error.
- Hooks not supported by this renderer
- handleCommitFiberRoot not supported by this renderer
- handleCommitFiberUnmount not supported by this renderer
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/02d595897f222b9b.
Report an issue: GitHub.