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

  1. Switch the import to a namespace import: `import * as ActionCreators from './actions'` and verify the module uses named exports (export const addTodo = ...).
  2. If the module has a default export, keep `import ActionCreators from './actions'` and confirm the default export is an object of functions.
  3. Before calling, log typeof ActionCreators and Object.keys(ActionCreators) to confirm it is a non-null object whose values are functions.
  4. 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

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


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