{"record":{"id":"709d2cc5ee79b083","repo":"marmelab/react-admin","slug":"failed-to-reuse-custom-theme-from-store","errorCode":null,"errorMessage":"Failed to reuse custom theme from store","messagePattern":"Failed to reuse custom theme from store","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/ra-ui-materialui/src/theme/ThemeProvider.tsx","lineNumber":46,"sourceCode":" *      </ThemeProvider>\n *   </ThemesContext.Provider>\n * );\n */\nexport const ThemeProvider = ({ children }: ThemeProviderProps) => {\n    const { lightTheme, darkTheme, defaultTheme } = useThemesContext();\n\n    const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)', {\n        noSsr: true,\n    });\n    const [mode] = useTheme(\n        defaultTheme || (prefersDarkMode && darkTheme ? 'dark' : 'light')\n    );\n\n    const themeValue = useMemo(() => {\n        try {\n            return createTheme(mode === 'dark' ? darkTheme : lightTheme);\n        } catch (e) {\n            console.warn('Failed to reuse custom theme from store', e);\n            return createTheme();\n        }\n    }, [mode, lightTheme, darkTheme]);\n\n    return (\n        <MuiThemeProvider theme={themeValue}>\n            {/* Had to cast here because Provider only accepts ReactNode but we might have a render function */}\n            {children as ReactNode}\n        </MuiThemeProvider>\n    );\n};\n\nexport interface ThemeProviderProps {\n    children: AdminChildren;\n}\n","sourceCodeStart":28,"sourceCodeEnd":62,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-ui-materialui/src/theme/ThemeProvider.tsx#L28-L62","documentation":"ThemeProvider wraps createTheme() in a try/catch when building the MUI theme from the lightTheme/darkTheme objects taken from the store. If the stored custom theme is invalid, createTheme throws and the library logs this warning instead of crashing, then falls back to the default Material UI theme. It means your custom theme object passed to <Admin theme={...}> could not be consumed by @mui/material's createTheme.","triggerScenarios":"Passing a theme object to <Admin theme={...}> (stored via react-admin's store) whose shape breaks createTheme: e.g. a v4 MUI theme (with old palette fields like type: 'dark') used with MUI v5, a theme built by a mismatched @mui/material version, a theme containing invalid palette/typography/shape values (wrong types, invalid tone numbers, malformed components overrides), or a null/undefined value where an object is expected in the overrides.","commonSituations":"Upgrading react-admin from v4 to v5 without migrating the theme from MUI v4 (palette.type -> palette.mode); mixing @mui/material versions via duplicate node_modules; hand-editing a theme and introducing a typo or wrong type; importing a theme from a tutorial built for an older MUI release.","solutions":["Migrate the theme to the MUI v5 format: replace palette.type with palette.mode ('light'|'dark') and remove any options removed in MUI v5.","Verify @mui/material resolves to a single version (npm ls @mui/material) and dedupe if multiple copies exist.","Validate the theme by calling createTheme(myTheme) yourself in isolation; the thrown message identifies the offending key.","Remove or minimize the theme object piece by piece (palette, components, typography) to find the invalid section.","If no custom theme is needed, omit the theme prop so the default light/dark themes are used."],"exampleFix":"// before (MUI v4 theme)\nconst theme = { palette: { type: 'dark', primary: { main: '#90caf9' } } };\n<Admin theme={theme} ...>\n\n// after (MUI v5 theme)\nconst theme = { palette: { mode: 'dark', primary: { main: '#90caf9' } } };\n<Admin theme={theme} ...>","handlingStrategy":"fallback","validationCode":"import { createTheme } from '@mui/material/styles';\ntry {\n  createTheme(myTheme);\n} catch (e) {\n  console.error('Invalid theme, fix before passing to <Admin>:', e);\n}","typeGuard":"const isPlainThemeObject = (t: unknown): t is Record<string, unknown> =>\n  typeof t === 'object' && t !== null && !Array.isArray(t) &&\n  !(typeof t === 'function');","tryCatchPattern":"let theme;\ntry {\n  theme = createTheme(customTheme);\n} catch (e) {\n  console.warn('Falling back to default theme', e);\n  theme = createTheme();\n}","preventionTips":["Always build themes with createTheme() from @mui/material/styles instead of hand-rolled plain objects.","Keep @mui/material and @emotion deps on a single version across the app (check npm ls).","When migrating react-admin versions, run the MUI codemods / migration guide for palette.type -> palette.mode.","Test theme rendering in dev with console warnings visible before shipping."],"tags":["react-admin","mui","theme","warning","fallback"],"backgroundTag":"invalid-theme-object","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}