{"record":{"id":"9b7a04a77cb19a1a","repo":"shadcn-ui/ui","slug":"usethemeconfig-must-be-used-within-an-activethemep","errorCode":null,"errorMessage":"useThemeConfig must be used within an ActiveThemeProvider","messagePattern":"useThemeConfig must be used within an ActiveThemeProvider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/v4/components/active-theme.tsx","lineNumber":53,"sourceCode":"        document.body.classList.remove(className)\n      })\n    document.body.classList.add(`theme-${activeTheme}`)\n    if (activeTheme.endsWith(\"-scaled\")) {\n      document.body.classList.add(\"theme-scaled\")\n    }\n  }, [activeTheme])\n\n  return (\n    <ThemeContext.Provider value={{ activeTheme, setActiveTheme }}>\n      {children}\n    </ThemeContext.Provider>\n  )\n}\n\nexport function useThemeConfig() {\n  const context = useContext(ThemeContext)\n  if (context === undefined) {\n    throw new Error(\"useThemeConfig must be used within an ActiveThemeProvider\")\n  }\n  return context\n}\n","sourceCodeStart":35,"sourceCodeEnd":57,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/apps/v4/components/active-theme.tsx#L35-L57","documentation":"`useThemeConfig` reads `ThemeContext` (created via `createContext` without an explicit default). The provider stores `{ activeTheme, setActiveTheme }` (setActiveTheme memoized on activeTheme). When `useContext(ThemeContext) === undefined`, the hook throws — consumers must always receive a concrete active theme.","triggerScenarios":"Calling `useThemeConfig()` in a component rendered outside `<ActiveThemeProvider>`, e.g. a header/theme-switch mounted in a root layout that sits above the provider, or a page-level component used before the provider wraps the tree.","commonSituations":"Moving ActiveThemeProvider from the root layout into a nested segment; SSR/tree-shaking stripping the provider; testing a themed component without the provider.","solutions":["Place `<ActiveThemeProvider>` high enough in the tree (typically the root layout) so every `useThemeConfig()` consumer is a descendant.","If a root-level component needs the theme, either move it under the provider or lift the provider above it.","Wrap test renders in `<ActiveThemeProvider>`."],"exampleFix":"// before\n<ThemeSwitch />  // rendered above ActiveThemeProvider\n\n// after\n<ActiveThemeProvider>\n  <ThemeSwitch />\n</ActiveThemeProvider>","handlingStrategy":"type-guard","validationCode":"render(<ActiveThemeProvider>{<ThemedComponent/>}</ActiveThemeProvider>)","typeGuard":"import { useContext } from \"react\"\nimport { ThemeContext } from \"@/components/active-theme\"\nfunction hasThemeConfig(): boolean {\n  return useContext(ThemeContext) !== undefined\n}","tryCatchPattern":"try { useThemeConfig() } catch (e) { if (e.message.includes(\"ActiveThemeProvider\")) {/*mount provider*/} throw e }","preventionTips":["Mount ActiveThemeProvider at the root layout, above any themed component.","Never render ThemeSwitch/useThemeConfig consumers above the provider.","Add ActiveThemeProvider to global story/test decorators."],"tags":["react","context","hooks","shadcn-v4","theming"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}