reduxjs/redux · error · Error
bindActionCreators expected an object or a function, but ins
Error message
bindActionCreators expected an object or a function, but instead received: '${kindOf(actionCreators)}'. Did you write "import ActionCreators from" instead of "import * as ActionCreators from"? What it means
bindActionCreators wraps either a single action creator or a map of them so they auto-dispatch. It throws when the first argument is neither a function nor a non-null object. The hint about import syntax targets the single most frequent cause: a default import that yields undefined when the module exports a namespace.
Source
Thrown at src/bindActionCreators.ts:67
export default function bindActionCreators<
A,
M extends ActionCreatorsMapObject<A>
>(actionCreators: M, dispatch: Dispatch): M
export default function bindActionCreators<
M extends ActionCreatorsMapObject,
N extends ActionCreatorsMapObject
>(actionCreators: M, dispatch: Dispatch): N
export default function bindActionCreators(
actionCreators: ActionCreator<any> | ActionCreatorsMapObject,
dispatch: Dispatch
) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error(
`bindActionCreators expected an object or a function, but instead received: '${kindOf(
actionCreators
)}'. ` +
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
)
}
const boundActionCreators: ActionCreatorsMapObject = {}
for (const key in actionCreators) {
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
View on GitHub (pinned to 3084fc33bb)
Solutions
- Switch the import to a namespace import: `import * as ActionCreators from './actions'` and verify the module uses named exports (export const addTodo = ...).
- If the module has a default export, keep `import ActionCreators from './actions'` and confirm the default export is an object of functions.
- Before calling, log typeof ActionCreators and Object.keys(ActionCreators) to confirm it is a non-null object whose values are functions.
- For CommonJS interop, use ActionCreators.default when require() returns { default: {...}, __esModule: true }.
Example fix
// before (actions.ts uses named exports) import ActionCreators from './actions' // ActionCreators is undefined bindActionCreators(ActionCreators, dispatch) // throws // after import * as ActionCreators from './actions' bindActionCreators(ActionCreators, dispatch)
Defensive patterns
Strategy: validation
Validate before calling
const isActionCreatorMap = x =>
x !== null && typeof x === 'object' &&
Object.values(x).every(v => typeof v !== 'function' || true)
if (typeof actionCreators !== 'function' && !isActionCreatorMap(actionCreators)) {
console.error('bindActionCreators: invalid first arg', actionCreators)
} else {
bound = bindActionCreators(actionCreators, dispatch)
} Type guard
const isActionCreatorsMap = (x): x is Record<string, (...a:any[])=>any> => x !== null && typeof x === 'object' const isActionCreatorFn = (x): x is (...a:any[])=>any => typeof x === 'function'
Try / catch
try {
bindActionCreators(actionCreators, dispatch)
} catch (e) {
if (/expected an object or a function/.test(e.message)) {
console.error('Check your action-creators import:', actionCreators)
}
throw e
} Prevention
- Use `import * as X from './actions'` for modules with named exports.
- Run a quick typeof check on the import before binding.
- Prefer named re-exports in barrel files to keep default/namespace semantics unambiguous.
When it happens
Trigger: Calling bindActionCreators(undefined, dispatch) or bindActionCreators(someString, dispatch); default-importing a module that only has named exports so the import value is undefined; destructuring an action-creators object incorrectly and passing the outer module namespace; passing an array instead of an object map.
Common situations: Writing `import ActionCreators from './actions'` instead of `import * as ActionCreators from './actions'` when actions.ts uses named exports; renaming an action-creators module and forgetting to update the import; re-export bugs where a barrel file does not actually re-export the symbol; mixing CommonJS require() with ESM where the namespace is nested under .default.
Related errors
- Expected the root reducer to be a function. Instead, receive
- Expected the nextReducer to be a function. Instead, received
- Dispatching while constructing your middleware is not allowe
- The slice reducer for key "${key}" returned undefined during
- The slice reducer for key "${key}" returned undefined when p
AI-assisted analysis of reduxjs/redux@3084fc33bb (2026-08-12).
Data as JSON: /api/errors/381cf1d8ee7fbc15.
Report an issue: GitHub.