emotion-js/emotion · error · Error
[ThemeProvider] Please make your theme prop a plain object
Error message
[ThemeProvider] Please make your theme prop a plain object
What it means
getTheme() in @emotion/react's ThemeProvider validates the theme prop itself: it must be a non-null, non-array object (or a function returning one). Passing null, undefined, a string, a number, or an array as the theme prop triggers this development-mode error. The library needs a spreadable object to merge with the outer theme.
Source
Thrown at packages/react/src/theming.tsx:52
if (typeof theme === 'function') {
const mergedTheme = theme(outerTheme)
if (
isDevelopment &&
(mergedTheme == null ||
typeof mergedTheme !== 'object' ||
Array.isArray(mergedTheme))
) {
throw new Error(
'[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'
)
}
return mergedTheme
}
if (
isDevelopment &&
(theme == null || typeof theme !== 'object' || Array.isArray(theme))
) {
throw new Error(
'[ThemeProvider] Please make your theme prop a plain object'
)
}
return { ...outerTheme, ...theme }
}
let createCacheWithTheme = /* #__PURE__ */ weakMemoize((outerTheme: Theme) => {
return weakMemoize((theme: Partial<Theme> | ((theme: Theme) => Theme)) => {
return getTheme(outerTheme, theme)
})
})
export interface ThemeProviderProps {
theme: Partial<Theme> | ((outerTheme: Theme) => Theme)
children: React.ReactNode
}
View on GitHub (pinned to b882bcba85)
Solutions
- Initialize theme state to an object, e.g. useState({}) instead of useState(null)
- Pass theme={theme ?? {}} to guard against null/undefined
- Convert string themes to objects: theme={themes[name]} where themes is a record of objects
- If representing multiple themes, merge them into one object rather than passing an array
Example fix
// before
<ThemeProvider theme={themeLoading ? null : currentTheme}>
// after
<ThemeProvider theme={themeLoading ? {} : currentTheme}> Defensive patterns
Strategy: type-guard
Validate before calling
if (theme == null || typeof theme !== 'object' || Array.isArray(theme)) {
throw new TypeError('ThemeProvider requires a plain object theme')
} Type guard
function isThemeObject(t: unknown): t is Record<string, unknown> {
return typeof t === 'object' && t !== null && !Array.isArray(t)
} Try / catch
try {
render(<ThemeProvider theme={theme}>{children}</ThemeProvider>)
} catch (e) {
if (String(e.message).includes('plain object')) {
render(<ThemeProvider theme={{}}>{children}</ThemeProvider>)
} else throw e
} Prevention
- Initialize theme state to {} rather than null
- Validate external/theme-config data before passing it to ThemeProvider
- Use TypeScript types (Record<string, unknown>) on the theme prop source to catch arrays/strings at compile time
When it happens
Trigger: <ThemeProvider theme={null}>, theme={undefined}, theme={'dark'}, theme={[...]} — any non-object, non-function value for the theme prop, evaluated when isDevelopment. Also spreading an array as theme via { ...outerTheme, ...theme } is explicitly blocked.
Common situations: State that holds the theme initialized to null before mounting (theme={themeState}); passing a theme string like 'dark' instead of an object; mapping an array of theme tokens directly as the theme; optional chaining yielding undefined.
Related errors
- [ThemeProvider] Please return an object from your theme func
- css can only be used during render
- cx can only be used during render
- Strings are not allowed as css prop values, please wrap it i
- You are trying to create a styled element with an undefined
AI-assisted analysis of emotion-js/emotion@b882bcba85 (2026-09-02).
Data as JSON: /api/errors/2e46c6d21a76bcce.
Report an issue: GitHub.