reduxjs/redux · error · Error
Expected the listener to be a function. Instead, received: '
Error message
Expected the listener to be a function. Instead, received: '${kindOf(listener)}' What it means
store.subscribe(listener) requires listener to be a function; it is invoked on every dispatch. Passing anything else (undefined, object, string) means there is nothing to call back, so Redux rejects it immediately with a kindOf() report of what was actually passed.
Source
Thrown at src/createStore.ts:203
*
* 1. The subscriptions are snapshotted just before every `dispatch()` call.
* If you subscribe or unsubscribe while the listeners are being invoked, this
* will not have any effect on the `dispatch()` that is currently in progress.
* However, the next `dispatch()` call, whether nested or not, will use a more
* recent snapshot of the subscription list.
*
* 2. The listener should not expect to see all state changes, as the state
* might have been updated multiple times during a nested `dispatch()` before
* the listener is called. It is, however, guaranteed that all subscribers
* registered before the `dispatch()` started will be called with the latest
* state by the time it exits.
*
* @param listener A callback to be invoked on every dispatch.
* @returns A function to remove this change listener.
*/
function subscribe(listener: () => void) {
if (typeof listener !== 'function') {
throw new Error(
`Expected the listener to be a function. Instead, received: '${kindOf(
listener
)}'`
)
}
if (isDispatching) {
throw new Error(
'You may not call store.subscribe() while the reducer is executing. ' +
'If you would like to be notified after the store has been updated, subscribe from a ' +
'component and invoke store.getState() in the callback to access the latest state. ' +
'See https://redux.js.org/api/store#subscribelistener for more details.'
)
}
let isSubscribed = true
ensureCanMutateNextListeners()View on GitHub (pinned to 3084fc33bb)
Solutions
- Pass a plain function: `store.subscribe(() => console.log(store.getState()))`.
- If you intended observer-pattern semantics, use the observable interop: `store[Symbol.observable]().subscribe({ next: state => ... })`.
- Bind extracted methods: `store.subscribe(myObj.onChange.bind(myObj))`.
- Default-check the argument before subscribing: `if (typeof cb === 'function') unsub = store.subscribe(cb)`.
Example fix
// before
store.subscribe({ next: () => render() }) // object, not function
// after
const unsub = store.subscribe(() => render())
// or use the observable interop for observer objects:
store[Symbol.observable]().subscribe({ next: state => render() }) Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof listener !== 'function') {
throw new TypeError(`listener must be a function, got ${typeof listener}`)
}
const unsub = store.subscribe(listener) Type guard
const isListener = (x): x is () => void => typeof x === 'function'
Prevention
- Pass a plain function to store.subscribe().
- For observer objects, use store[Symbol.observable]().subscribe(observer).
- Bind extracted methods before subscribing.
When it happens
Trigger: store.subscribe() with no argument; store.subscribe({ next: fn }) (passing an observer object to subscribe instead of the observable interop); store.subscribe(myObj.onChange) without binding `this` losing the function reference; subscribe(null) by accident.
Common situations: Confusing store.subscribe(listener) with store[Symbol.observable]().subscribe(observer) — the latter takes an object, the former a function; destructuring a method off an object without binding; passing a React component as the listener; legacy code passing an event-emitter.
Related errors
- Expected the enhancer to be a function. Instead, received: '
- You may not call store.subscribe() while the reducer is exec
- You may not unsubscribe from a store listener while the redu
- Expected the observer to be an object. Instead, received: '$
- Expected the root reducer to be a function. Instead, receive
AI-assisted analysis of reduxjs/redux@3084fc33bb (2026-08-12).
Data as JSON: /api/errors/8ea5b8bf092576d0.
Report an issue: GitHub.