reduxjs/redux · error · Error
The slice reducer for key "${key}" returned undefined during
Error message
The slice reducer for key "${key}" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined. What it means
combineReducers runs assertReducerShape during store creation, invoking every slice reducer with (undefined, { type: INIT }). Each reducer must return its initial state when state is undefined. Returning undefined means the slice has no defined starting value, which would corrupt the combined state tree, so Redux fails fast.
Source
Thrown at src/combineReducers.ts:70
if (unexpectedKeys.length > 0) {
return (
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
`"${unexpectedKeys.join('", "')}" found in ${argumentName}. ` +
`Expected to find one of the known reducer keys instead: ` +
`"${reducerKeys.join('", "')}". Unexpected keys will be ignored.`
)
}
}
function assertReducerShape(reducers: {
[key: string]: Reducer<any, any, any>
}) {
Object.keys(reducers).forEach(key => {
const reducer = reducers[key]
const initialState = reducer(undefined, { type: ActionTypes.INIT })
if (typeof initialState === 'undefined') {
throw new Error(
`The slice reducer for key "${key}" returned undefined during initialization. ` +
`If the state passed to the reducer is undefined, you must ` +
`explicitly return the initial state. The initial state may ` +
`not be undefined. If you don't want to set a value for this reducer, ` +
`you can use null instead of undefined.`
)
}
if (
typeof reducer(undefined, {
type: ActionTypes.PROBE_UNKNOWN_ACTION()
}) === 'undefined'
) {
throw new Error(
`The slice reducer for key "${key}" returned undefined when probed with a random type. ` +
`Don't try to handle '${ActionTypes.INIT}' or other actions in "redux/*" ` +
`namespace. They are considered private. Instead, you must return the ` +
`current state for any unknown actions, unless it is undefined, ` +View on GitHub (pinned to 3084fc33bb)
Solutions
- Add the default-parameter initializer: `function reducer(state = initialState, action) { ... }` so undefined state resolves to a concrete value.
- Ensure the reducer's switch ends with `default: return state` so any action (including INIT) returns the prior (initial) state.
- Use null instead of undefined if the slice legitimately starts empty: `state = null`.
- After fixing, run the store creation again — assertReducerShape re-probes automatically.
Example fix
// before
function todos(state, action) {
switch (action.type) {
case 'ADD': return [...state, action.payload]
}
}
// after
function todos(state = [], action) {
switch (action.type) {
case 'ADD': return [...state, action.payload]
default: return state
}
} Defensive patterns
Strategy: validation
Validate before calling
// Probe every slice before passing to combineReducers:
const probeSlices = slices => {
for (const [key, reducer] of Object.entries(slices)) {
if (typeof reducer(undefined, { type: '@@INIT' }) === 'undefined') {
throw new Error(`Slice '${key}' returns undefined for initial state`)
}
}
}
probeSlices({ todos, filter }) Type guard
const hasInitialState = reducer =>
typeof reducer(undefined, { type: '@@PROBE' }) !== 'undefined' Prevention
- Always declare reducer state with a default parameter: `state = initialState`.
- Add `default: return state` to every reducer switch.
- Write a unit test that calls each reducer with (undefined, { type: '@@INIT' }) and asserts a defined result.
When it happens
Trigger: A slice reducer written as (state = initialState, action) => { switch(action.type){...} } where the default-parameter initializer was omitted; a reducer that returns undefined because no case matched and there is no `default: return state` and no initial-state default; a reducer that conditionally returns based on action.type with no fallback for INIT.
Common situations: Forgetting the ES2015 default parameter `state = initialState`; reducer authored with an early `if (action.type === ...) return ...` and a bare `return` at the end; refactoring that accidentally deletes the default-parameter line; converting a TypeScript reducer and typing state as `S | undefined` without the default.
Related errors
- The slice reducer for key "${key}" returned undefined when p
- When called with an action of type ${actionType ? `"${String
- Expected the root reducer to be a function. Instead, receive
- You may not call store.getState() while the reducer is execu
- Reducers may not dispatch actions.
AI-assisted analysis of reduxjs/redux@3084fc33bb (2026-08-12).
Data as JSON: /api/errors/fc7cef07dc2dea6b.
Report an issue: GitHub.