{"record":{"id":"3d203f05a3a4e88f","repo":"reduxjs/redux","slug":"action-type-property-must-be-a-string-instead","errorCode":null,"errorMessage":"Action \"type\" property must be a string. Instead, the actual type was: '${kindOf(action.type)}'. Value was: '${String(action.type)}' (stringified)","messagePattern":"Action \"type\" property must be a string\\. Instead, the actual type was: '(.+?)'\\. Value was: '(.+?)' \\(stringified\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/createStore.ts","lineNumber":286,"sourceCode":"   * return something else (for example, a Promise you can await).\n   */\n  function dispatch(action: A) {\n    if (!isPlainObject(action)) {\n      throw new Error(\n        `Actions must be plain objects. Instead, the actual type was: '${kindOf(\n          action\n        )}'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.`\n      )\n    }\n\n    if (typeof action.type === 'undefined') {\n      throw new Error(\n        'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.'\n      )\n    }\n\n    if (typeof action.type !== 'string') {\n      throw new Error(\n        `Action \"type\" property must be a string. Instead, the actual type was: '${kindOf(\n          action.type\n        )}'. Value was: '${String(action.type)}' (stringified)`\n      )\n    }\n\n    if (isDispatching) {\n      throw new Error('Reducers may not dispatch actions.')\n    }\n\n    try {\n      isDispatching = true\n      currentState = currentReducer(currentState, action)\n    } finally {\n      isDispatching = false\n    }\n\n    const listeners = (currentListeners = nextListeners)","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/reduxjs/redux/blob/3084fc33bb23ab4cab4796172eafe342da4e73d9/src/createStore.ts#L268-L304","documentation":"After confirming type is defined, Redux also requires type to be a string. Symbols, numbers, objects, or booleans as type break devtools serialization, action recording, and string-based switch matching in reducers. The error includes kindOf and the stringified value to surface exactly what was passed.","triggerScenarios":"dispatch({ type: Symbol('X') }) — using a Symbol type; dispatch({ type: 1 }) numeric type; dispatch({ type: { ns: 'X' } }) object type; a constants module that exports Symbols instead of strings (common in some Flux libraries).","commonSituations":"Mixing a Flux-constants library that exports Symbols; using enum numeric values from TypeScript as action types; intentional opaque types for namespacing that should instead use string prefixes; migrated code where types changed from string to Symbol.","solutions":["Use string constants for action types: `export const ADD_TODO = 'todos/add'`.","If you want namespacing, prefix the string ('feature/ACTION') instead of using Symbols.","Audit constant modules to confirm every exported type is `as const` string literal.","If using a Symbol-based library, wrap it with middleware that maps Symbols to strings before they reach dispatch."],"exampleFix":"// before\nconst ADD_TODO = Symbol('add')\ndispatch({ type: ADD_TODO, payload: x })  // type is symbol -> throws\n\n// after\nconst ADD_TODO = 'todos/add' as const\ndispatch({ type: ADD_TODO, payload: x })","handlingStrategy":"type-guard","validationCode":"if (typeof action.type !== 'string') {\n  throw new TypeError(`Action type must be a string, got ${typeof action.type}`)\n}\nstore.dispatch(action)","typeGuard":"const hasStringType = (a): a is { type: string } =>\n  a !== null && typeof a === 'object' && typeof (a as any).type === 'string'","tryCatchPattern":null,"preventionTips":["Use string constants (or `as const` literals) for action types, never Symbols/numbers.","Namespace via string prefixes ('feature/ACTION').","Audit constant modules to ensure every type is a string literal.","Type-check action creators so type is always a string."],"tags":["redux","createstore","dispatch","action-type","string-validation"],"backgroundTag":null,"analyzedSha":"3084fc33bb23ab4cab4796172eafe342da4e73d9","analyzedAt":"2026-08-12T13:21:41.727Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}