{"record":{"id":"fc7cef07dc2dea6b","repo":"reduxjs/redux","slug":"the-slice-reducer-for-key-key-returned-undefi","errorCode":null,"errorMessage":"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.","messagePattern":"The slice reducer for 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\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/combineReducers.ts","lineNumber":70,"sourceCode":"  if (unexpectedKeys.length > 0) {\n    return (\n      `Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +\n      `\"${unexpectedKeys.join('\", \"')}\" found in ${argumentName}. ` +\n      `Expected to find one of the known reducer keys instead: ` +\n      `\"${reducerKeys.join('\", \"')}\". Unexpected keys will be ignored.`\n    )\n  }\n}\n\nfunction assertReducerShape(reducers: {\n  [key: string]: Reducer<any, any, any>\n}) {\n  Object.keys(reducers).forEach(key => {\n    const reducer = reducers[key]\n    const initialState = reducer(undefined, { type: ActionTypes.INIT })\n\n    if (typeof initialState === 'undefined') {\n      throw new Error(\n        `The slice reducer for key \"${key}\" returned undefined during initialization. ` +\n          `If the state passed to the reducer is undefined, you must ` +\n          `explicitly return the initial state. The initial state may ` +\n          `not be undefined. If you don't want to set a value for this reducer, ` +\n          `you can use null instead of undefined.`\n      )\n    }\n\n    if (\n      typeof reducer(undefined, {\n        type: ActionTypes.PROBE_UNKNOWN_ACTION()\n      }) === 'undefined'\n    ) {\n      throw new Error(\n        `The slice reducer for key \"${key}\" returned undefined when probed with a random type. ` +\n          `Don't try to handle '${ActionTypes.INIT}' or other actions in \"redux/*\" ` +\n          `namespace. They are considered private. Instead, you must return the ` +\n          `current state for any unknown actions, unless it is undefined, ` +","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/reduxjs/redux/blob/3084fc33bb23ab4cab4796172eafe342da4e73d9/src/combineReducers.ts#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfunction todos(state, action) {\n  switch (action.type) {\n    case 'ADD': return [...state, action.payload]\n  }\n}\n\n// after\nfunction todos(state = [], action) {\n  switch (action.type) {\n    case 'ADD': return [...state, action.payload]\n    default: return state\n  }\n}","handlingStrategy":"validation","validationCode":"// Probe every slice before passing to combineReducers:\nconst probeSlices = slices => {\n  for (const [key, reducer] of Object.entries(slices)) {\n    if (typeof reducer(undefined, { type: '@@INIT' }) === 'undefined') {\n      throw new Error(`Slice '${key}' returns undefined for initial state`)\n    }\n  }\n}\nprobeSlices({ todos, filter })","typeGuard":"const hasInitialState = reducer =>\n  typeof reducer(undefined, { type: '@@PROBE' }) !== 'undefined'","tryCatchPattern":null,"preventionTips":["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."],"tags":["redux","combinereducers","reducer","init","state"],"backgroundTag":null,"analyzedSha":"3084fc33bb23ab4cab4796172eafe342da4e73d9","analyzedAt":"2026-08-12T13:21:41.727Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}