{"record":{"id":"9a00a12efb5134ca","repo":"facebook/react","slug":"rendered-more-hooks-than-during-the-previous-rende","errorCode":null,"errorMessage":"Rendered more hooks than during the previous render","messagePattern":"Rendered more hooks than during the previous render","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-server/src/ReactFizzHooks.js","lineNumber":239,"sourceCode":"        `[${nextDeps.join(', ')}]`,\n        `[${prevDeps.join(', ')}]`,\n      );\n    }\n  }\n  // $FlowFixMe[incompatible-use] found when upgrading Flow\n  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {\n    // $FlowFixMe[incompatible-use] found when upgrading Flow\n    if (is(nextDeps[i], prevDeps[i])) {\n      continue;\n    }\n    return false;\n  }\n  return true;\n}\n\nfunction createHook(): Hook {\n  if (numberOfReRenders > 0) {\n    throw new Error('Rendered more hooks than during the previous render');\n  }\n  return {\n    memoizedState: null,\n    queue: null,\n    next: null,\n  };\n}\n\nfunction createWorkInProgressHook(): Hook {\n  if (workInProgressHook === null) {\n    // This is the first hook in the list\n    if (firstWorkInProgressHook === null) {\n      isReRender = false;\n      firstWorkInProgressHook = workInProgressHook = createHook();\n    } else {\n      // There's already a work-in-progress. Reuse it.\n      isReRender = true;\n      workInProgressHook = firstWorkInProgressHook;","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server/src/ReactFizzHooks.js#L221-L257","documentation":"When a server render re-runs because of render-phase updates, Fizz reuses the hook list built in the previous pass. createHook throws when a re-render must allocate a hook beyond that list — the component called more hooks than the previous render, which is the Rules of Hooks violation 'never call hooks conditionally'.","triggerScenarios":"Conditional hooks in a server-rendered component: if (cond) useState(...), a hook placed after an early return, or hooks inside loops with varying iteration counts. The violation surfaces on the re-render pass triggered by a render-phase update (a setter called during render).","commonSituations":"Client components with conditional hooks being SSR'd; refactors that introduce an early return above existing hooks; derived-state code whose setState during render triggers the second pass that exposes the order drift.","solutions":["Move every hook above conditionals and early returns so the same hooks run in the same order every render","Replace conditional hooks with conditional use of results: call the hook unconditionally, then branch on its value","Enable eslint-plugin-react-hooks (rules-of-hooks) so this class of bug fails statically"],"exampleFix":"// before\nfunction Detail({item}) {\n  if (!item) return null;\n  const [tab, setTab] = useState(0); // hook after early return\n  return <div>{item[tab]}</div>;\n}\n\n// after\nfunction Detail({item}) {\n  const [tab, setTab] = useState(0); // always called\n  if (!item) return null;\n  return <div>{item[tab]}</div>;\n}","handlingStrategy":"validation","validationCode":"// .eslintrc: catch conditional hooks statically before any SSR run\n// {\n//   \"extends\": [\"plugin:react-hooks/recommended\"]\n// }\n// Rules of Hooks violations (conditional hooks, early returns above hooks) fail lint instead of SSR.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all hooks above conditionals and early returns, in the same order every render","Run eslint-plugin-react-hooks in CI so rules-of-hooks violations never reach SSR","After refactors, check that no early return was introduced above an existing hook"],"tags":["hooks","rules-of-hooks","conditional-hooks","ssr","fizz"],"backgroundTag":"rules-of-hooks-violation","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}