{"record":{"id":"c7e9664453402175","repo":"shadcn-ui/ui","slug":"usehistory-must-be-used-within-historyprovider","errorCode":null,"errorMessage":"useHistory must be used within HistoryProvider","messagePattern":"useHistory must be used within HistoryProvider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/v4/app/(app)/(create)/hooks/use-history.tsx","lineNumber":182,"sourceCode":"  const value = React.useMemo(\n    () => ({ canGoBack, canGoForward, goBack, goForward }),\n    [canGoBack, canGoForward, goBack, goForward]\n  )\n\n  return (\n    <HistoryContext value={value}>\n      <Suspense>\n        <PresetSync onPresetChange={onPresetChange} />\n      </Suspense>\n      {children}\n    </HistoryContext>\n  )\n}\n\nexport function useHistory() {\n  const context = React.useContext(HistoryContext)\n  if (!context) {\n    throw new Error(\"useHistory must be used within HistoryProvider\")\n  }\n  return context\n}\n","sourceCodeStart":164,"sourceCodeEnd":186,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/apps/v4/app/(app)/(create)/hooks/use-history.tsx#L164-L186","documentation":"`useHistory` reads `HistoryContext`; the provider is `HistoryProvider`, which also mounts a `<PresetSync>` Suspense boundary. Calling `useHistory()` where `React.useContext(HistoryContext)` returns undefined throws — guaranteeing consumers always see `{ ... }` (history stack, push/redo, etc.) rather than a silent undefined.","triggerScenarios":"Using `useHistory()` in a component rendered outside `<HistoryProvider>`, or before the provider has mounted in the (create) subtree. Also when a lazy-loaded component under Suspense resolves after the provider was removed from the tree.","commonSituations":"Refactoring the create-app layout and dropping the provider; adding a child route whose page uses history but whose parent layout no longer wraps with HistoryProvider; integration tests rendering a single panel.","solutions":["Ensure every component calling `useHistory()` is a descendant of `<HistoryProvider>`.","Re-add `<HistoryProvider onPresetChange={...}>{children}</HistoryProvider>` at the (create) layout root if it was removed.","In tests, wrap the render in the provider (and a Suspense boundary, since PresetSync is mounted inside it)."],"exampleFix":"// before\nconst { history } = useHistory()\n\n// after\n<HistoryProvider onPresetChange={handlePreset}>\n  <ComponentThatUsesHistory />\n</HistoryProvider>","handlingStrategy":"type-guard","validationCode":"// Wrap any isolated render of a history consumer:\nrender(<HistoryProvider onPresetChange={() => {}}>{<Consumer/>}</HistoryProvider>)","typeGuard":"import React from \"react\"\nimport { HistoryContext } from \"@/(app)/(create)/hooks/use-history\"\nconst hasHistory = () => React.useContext(HistoryContext) != null","tryCatchPattern":"try {\n  useHistory()\n} catch (e) {\n  if (e.message.includes(\"HistoryProvider\")) { /* mount provider or fallback */ }\n  throw e\n}","preventionTips":["Always render HistoryProvider (with Suspense) at the (create) layout root.","Add the provider to all test decorators for history-consuming components.","Don't lift history-consuming components above the provider during refactor."],"tags":["react","context","hooks","shadcn-v4","history"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}