{"record":{"id":"02d595897f222b9b","repo":"facebook/react","slug":"unknown-fiber-needs-to-be-a-function-component-to","errorCode":null,"errorMessage":"Unknown Fiber. Needs to be a function component to inspect hooks.","messagePattern":"Unknown Fiber\\. Needs to be a function component to inspect hooks\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-debug-tools/src/ReactDebugHooks.js","lineNumber":1347,"sourceCode":"    }\n    return props;\n  }\n  return baseProps;\n}\n\n// Shared implementation. Requires an explicit dispatcher and never references\n// ReactSharedInternals (it delegates to inspectHooksImpl), so importing it does\n// not pull React into the bundle.\nfunction inspectHooksOfFiberImpl(\n  fiber: Fiber,\n  currentDispatcher: CurrentDispatcherRef,\n): HooksTree {\n  if (\n    fiber.tag !== FunctionComponent &&\n    fiber.tag !== SimpleMemoComponent &&\n    fiber.tag !== ForwardRef\n  ) {\n    throw new Error(\n      'Unknown Fiber. Needs to be a function component to inspect hooks.',\n    );\n  }\n\n  // Warm up the cache so that it doesn't consume the currentHook.\n  getPrimitiveStackCache();\n\n  // Set up the current hook so that we can step through and read the\n  // current state from them.\n  currentHook = fiber.memoizedState as Hook;\n  currentFiber = fiber;\n  const thenableState =\n    fiber.dependencies && fiber.dependencies._debugThenableState;\n  // In DEV the thenableState is an inner object.\n  const usedThenables: any = thenableState\n    ? thenableState.thenables || thenableState\n    : null;\n  currentThenableState = Array.isArray(usedThenables) ? usedThenables : null;","sourceCodeStart":1329,"sourceCodeEnd":1365,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-debug-tools/src/ReactDebugHooks.js#L1329-L1365","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ninspectHooksOfFiber(fiber); // throws for class/host/memo fibers\n\n// after\nconst INSPECTABLE = new Set(['FunctionComponent', 'SimpleMemoComponent', 'ForwardRef']);\nif (INSPECTABLE.has(fiber.type? fiber.type.name : '') || [0, 11, 15].includes(fiber.tag)) {\n  inspectHooksOfFiber(fiber);\n}","handlingStrategy":"type-guard","validationCode":"// before inspecting, confirm the fiber is a hooks-capable function component\nimport {FunctionComponent, SimpleMemoComponent, ForwardRef} from 'react-reconciler/src/ReactWorkTags';\n\nif (fiber.tag !== FunctionComponent && fiber.tag !== SimpleMemoComponent && fiber.tag !== ForwardRef) {\n  skipInspection(fiber); // class/host/memo fibers have no inspectable hooks\n}","typeGuard":"function canInspectHooks(fiber: Fiber): boolean {\n  return (\n    fiber.tag === FunctionComponent || // 0\n    fiber.tag === SimpleMemoComponent || // 15\n    fiber.tag === ForwardRef // 11\n  );\n}","tryCatchPattern":"try {\n  return inspectHooksOfFiber(fiber, currentDispatcher);\n} catch (e) {\n  if (e.message.includes('Needs to be a function component to inspect hooks')) {\n    return []; // not a hooks component; nothing to inspect\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["react","devtools","fiber","hooks","inspection","type-guard"],"backgroundTag":"unsupported-fiber-type","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}