reduxjs/redux · error · Error

When called with an action of type ${actionType ? `"${String

Error message

When called with an action of type ${actionType ? `"${String(actionType)}"` : '(unknown type)'}, the slice reducer for key "${key}" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.

What it means

Unlike errors 2/3 (which fire once at setup), this fires at runtime inside the combined reducer's dispatch loop: after running a slice for a real dispatched action, the slice returned undefined. combineReducers cannot store undefined in the next state tree because that would delete the slice, so it throws with the offending action type and slice key.

Source

Thrown at src/combineReducers.ts:186

        finalReducers,
        action,
        unexpectedKeyCache
      )
      if (warningMessage) {
        warning(warningMessage)
      }
    }

    let hasChanged = false
    const nextState: StateFromReducersMapObject<typeof reducers> = {}
    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i]
      const reducer = finalReducers[key]
      const previousStateForKey = state[key]
      const nextStateForKey = reducer(previousStateForKey, action)
      if (typeof nextStateForKey === 'undefined') {
        const actionType = action && action.type
        throw new Error(
          `When called with an action of type ${
            actionType ? `"${String(actionType)}"` : '(unknown type)'
          }, the slice reducer for key "${key}" returned undefined. ` +
            `To ignore an action, you must explicitly return the previous state. ` +
            `If you want this reducer to hold no value, you can return null instead of undefined.`
        )
      }
      nextState[key] = nextStateForKey
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    hasChanged =
      hasChanged || finalReducerKeys.length !== Object.keys(state).length
    return hasChanged ? nextState : state
  }
}

View on GitHub (pinned to 3084fc33bb)

Solutions

  1. Inspect the error message: the slice key and action type name the exact reducer and the action that triggered the undefined return.
  2. In that reducer's case for the named action, return the previous state (`return state`) to ignore it, or return a concrete value / null.
  3. Audit every case branch to confirm each returns a defined value; add `default: return state` if missing.
  4. If the slice should hold no value, return `null` explicitly, never `undefined`.

Example fix

// before
case 'CLEAR_TODO':
  return                  // returns undefined -> throws at runtime

// after
case 'CLEAR_TODO':
  return null            // explicit empty value is allowed
Defensive patterns

Strategy: try-catch

Validate before calling

// Wrap the combined reducer to catch undefined slice returns at runtime:
const safeCombine = reducers => {
  const combined = combineReducers(reducers)
  return (state, action) => {
    const next = combined(state, action)
    return next
  }
}
// (Note: real protection is fixing each slice; this only localizes failure.)

Type guard

// After dispatching, assert no slice is undefined:
const stateHasNoUndefined = state =>
  Object.values(state).every(v => v !== undefined)

Try / catch

try {
  store.dispatch(action)
} catch (e) {
  if (/returned undefined/.test(e.message)) {
    // inspect e.message for the slice key and action type, fix that case
  }
  throw e
}

Prevention

When it happens

Trigger: A slice reducer handles a specific action type by returning undefined (e.g. `case 'CLEAR': return` instead of `return null`); a reducer's switch added a new case that forgets to return; a reducer that does `state.map(...)` on an undefined nested value and falls through to undefined; reducer composition where a child reducer returns undefined for an action its parent forwarded.

Common situations: Adding a new action case that uses `return` with no value; refactoring that introduces an early branch returning undefined; reducers that filter state into an empty array then index `[0]` yielding undefined; migrating from Immutable.js where `.get()` returns undefined for missing keys.

Related errors


AI-assisted analysis of reduxjs/redux@3084fc33bb (2026-08-12). Data as JSON: /api/errors/4414af8b817cc796. Report an issue: GitHub.