{"record":{"id":"4414af8b817cc796","repo":"reduxjs/redux","slug":"when-called-with-an-action-of-type-actiontype","errorCode":null,"errorMessage":"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.","messagePattern":"When called with an action of type (.+?)\"` : '\\(unknown type\\)'\\}, the slice reducer for 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\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/combineReducers.ts","lineNumber":186,"sourceCode":"        finalReducers,\n        action,\n        unexpectedKeyCache\n      )\n      if (warningMessage) {\n        warning(warningMessage)\n      }\n    }\n\n    let hasChanged = false\n    const nextState: StateFromReducersMapObject<typeof reducers> = {}\n    for (let i = 0; i < finalReducerKeys.length; i++) {\n      const key = finalReducerKeys[i]\n      const reducer = finalReducers[key]\n      const previousStateForKey = state[key]\n      const nextStateForKey = reducer(previousStateForKey, action)\n      if (typeof nextStateForKey === 'undefined') {\n        const actionType = action && action.type\n        throw new Error(\n          `When called with an action of type ${\n            actionType ? `\"${String(actionType)}\"` : '(unknown type)'\n          }, the slice reducer for key \"${key}\" returned undefined. ` +\n            `To ignore an action, you must explicitly return the previous state. ` +\n            `If you want this reducer to hold no value, you can return null instead of undefined.`\n        )\n      }\n      nextState[key] = nextStateForKey\n      hasChanged = hasChanged || nextStateForKey !== previousStateForKey\n    }\n    hasChanged =\n      hasChanged || finalReducerKeys.length !== Object.keys(state).length\n    return hasChanged ? nextState : state\n  }\n}\n","sourceCodeStart":168,"sourceCodeEnd":202,"githubUrl":"https://github.com/reduxjs/redux/blob/3084fc33bb23ab4cab4796172eafe342da4e73d9/src/combineReducers.ts#L168-L202","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the error message: the slice key and action type name the exact reducer and the action that triggered the undefined return.","In that reducer's case for the named action, return the previous state (`return state`) to ignore it, or return a concrete value / null.","Audit every case branch to confirm each returns a defined value; add `default: return state` if missing.","If the slice should hold no value, return `null` explicitly, never `undefined`."],"exampleFix":"// before\ncase 'CLEAR_TODO':\n  return                  // returns undefined -> throws at runtime\n\n// after\ncase 'CLEAR_TODO':\n  return null            // explicit empty value is allowed","handlingStrategy":"try-catch","validationCode":"// Wrap the combined reducer to catch undefined slice returns at runtime:\nconst safeCombine = reducers => {\n  const combined = combineReducers(reducers)\n  return (state, action) => {\n    const next = combined(state, action)\n    return next\n  }\n}\n// (Note: real protection is fixing each slice; this only localizes failure.)","typeGuard":"// After dispatching, assert no slice is undefined:\nconst stateHasNoUndefined = state =>\n  Object.values(state).every(v => v !== undefined)","tryCatchPattern":"try {\n  store.dispatch(action)\n} catch (e) {\n  if (/returned undefined/.test(e.message)) {\n    // inspect e.message for the slice key and action type, fix that case\n  }\n  throw e\n}","preventionTips":["Audit every reducer case branch to ensure it returns a defined value.","End reducers with `default: return state`.","Return `null` (never undefined) when a slice should hold no value.","Add unit tests covering each action case for every slice."],"tags":["redux","combinereducers","reducer","runtime","undefined-return"],"backgroundTag":null,"analyzedSha":"3084fc33bb23ab4cab4796172eafe342da4e73d9","analyzedAt":"2026-08-12T13:21:41.727Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}