emotion-js/emotion · error · Error
[ThemeProvider] Please return an object from your theme func
Error message
[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}! What it means
@emotion/react's ThemeProvider getTheme() validates that the resolved theme is a non-null, non-array object. When the theme prop is a function, the function's return value (mergedTheme) is checked; if the function returns null, undefined, a primitive, or an array, this error is thrown in development. It exists because downstream emotion code destructures and spreads the theme and would otherwise fail with confusing errors.
Source
Thrown at packages/react/src/theming.tsx:42
if (isDevelopment) {
ThemeContext.displayName = 'EmotionThemeContext'
}
export const useTheme = () => React.useContext(ThemeContext)
const getTheme = (
outerTheme: Theme,
theme: Partial<Theme> | ((theme: Theme) => Theme)
): Theme => {
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) => {View on GitHub (pinned to b882bcba85)
Solutions
- Make the theme function always return a plain object, e.g. theme={() => ({ ...myTheme })}
- Guard inside the function: return loadedTheme ?? {} instead of null/undefined
- If the theme is a static object, pass it directly (theme={myTheme}) rather than wrapping it in a function that may return non-objects
- Ensure the return value is not an array; spread arrays into an object or restructure the theme
Example fix
// before
<ThemeProvider theme={() => config?.theme ?? null}>
// after
<ThemeProvider theme={() => config?.theme ?? {}}> Defensive patterns
Strategy: validation
Validate before calling
const resolved = typeof themeFn === 'function' ? themeFn(outerTheme) : themeFn
if (resolved == null || typeof resolved !== 'object' || Array.isArray(resolved)) {
throw new TypeError('theme function must return a plain object')
} Type guard
function isPlainTheme(t: unknown): t is Record<string, unknown> {
return t != null && typeof t === 'object' && !Array.isArray(t)
} Try / catch
try {
render(<ThemeProvider theme={makeTheme}>{children}</ThemeProvider>)
} catch (e) {
if (e.message.includes('[ThemeProvider]')) {
console.error('theme function returned a non-object; falling back to {}')
render(<ThemeProvider theme={{}}>{children}</ThemeProvider>)
} else throw e
} Prevention
- Type theme factories with a non-nullable object return type: () => Theme
- Never early-return null/undefined from theme functions; use ?? {}
- Add a unit test asserting the theme factory returns an object for all states
When it happens
Trigger: Passing theme={fn} to <ThemeProvider> where fn returns null, undefined, a primitive (string/number), or an array; e.g. theme={() => null} or a factory that conditionally returns nothing. Only thrown when isDevelopment.
Common situations: Theme factory functions that early-return null when config isn't loaded yet; refactored theme objects accidentally turned into arrays; async data that hasn't resolved so the factory returns undefined.
Related errors
- [ThemeProvider] Please make your theme prop a plain object
- 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/dbe9dbf6e2753d61.
Report an issue: GitHub.