reduxjs/redux · error · Error
Dispatching while constructing your middleware is not allowe
Error message
Dispatching while constructing your middleware is not allowed. Other middleware would not be applied to this dispatch.
What it means
applyMiddleware() assigns a temporary dispatch placeholder that throws whenever a middleware invokes store.dispatch while it is still being constructed. During setup the chain has not yet been composed onto the real store.dispatch, so any dispatch fired in that window would silently bypass all other middleware. Redux refuses to run it rather than emit a partial pipeline.
Source
Thrown at src/applyMiddleware.ts:59
middleware4: Middleware<Ext4, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 }>
export default function applyMiddleware<Ext1, Ext2, Ext3, Ext4, Ext5, S>(
middleware1: Middleware<Ext1, S, any>,
middleware2: Middleware<Ext2, S, any>,
middleware3: Middleware<Ext3, S, any>,
middleware4: Middleware<Ext4, S, any>,
middleware5: Middleware<Ext5, S, any>
): StoreEnhancer<{ dispatch: Ext1 & Ext2 & Ext3 & Ext4 & Ext5 }>
export default function applyMiddleware<Ext, S = any>(
...middlewares: Middleware<any, S, any>[]
): StoreEnhancer<{ dispatch: Ext }>
export default function applyMiddleware(
...middlewares: Middleware[]
): StoreEnhancer<any> {
return createStore => (reducer, preloadedState) => {
const store = createStore(reducer, preloadedState)
let dispatch: Dispatch = () => {
throw new Error(
'Dispatching while constructing your middleware is not allowed. ' +
'Other middleware would not be applied to this dispatch.'
)
}
const middlewareAPI: MiddlewareAPI = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, ...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose<typeof dispatch>(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}View on GitHub (pinned to 3084fc33bb)
Solutions
- Move the eager dispatch out of the middleware factory body and into the innermost handler (next => action => { ... }) or a side-effect scheduled after setup (queueMicrotask / a dedicated INIT action dispatched by the app).
- If you need an initial action, dispatch it from your application code after createStore(applyMiddleware(...)(...)) returns, not from inside the middleware constructor.
- If the dispatch is genuinely meant to run before the store is ready, restructure so the work happens in the next => action => layer where the composed dispatch is available.
Example fix
// before
const myMiddleware = ({ dispatch }) => {
dispatch({ type: 'MIDDLEWARE_READY' }) // throws: runs during construction
return next => action => next(action)
}
// after
const myMiddleware = ({ dispatch }) => {
return next => action => {
if (action.type === 'APP_INIT') dispatch({ type: 'MIDDLEWARE_READY' })
return next(action)
}
} Defensive patterns
Strategy: validation
Validate before calling
// No dispatch should run during middleware construction.
// Inspect each middleware factory body for calls to `dispatch`/`store.dispatch`
// BEFORE they are wrapped by `next => action => ...`.
const assertNoEagerDispatch = mw => {
const api = {
getState: () => ({}),
dispatch: () => { throw new Error('eager dispatch in middleware factory') }
}
mw(api) // triggers outer factory only; inner next=> is returned, not invoked
return true
} Type guard
const isMiddleware = x => typeof x === 'function' // Guard the call site so only well-formed middleware reaches applyMiddleware: const safeMiddlewares = middlewares.filter(isMiddleware)
Prevention
- Never call api.dispatch() inside the outer middleware factory body; only inside `next => action => ...`.
- Review each middleware for any dispatch that is not nested inside the next-handler.
- Add a unit test that calls applyMiddleware(...)(createStore)(reducer) with each middleware and asserts no throw.
When it happens
Trigger: A middleware function (the first curried arg handed ({ getState, dispatch }) => next => action => ...) calls middlewareAPI.dispatch(...) synchronously inside its outermost factory body, i.e. during middlewares.map(middleware => middleware(middlewareAPI)) at applyMiddleware.ts:69, before dispatch = compose(...chain)(store.dispatch) has assigned the real dispatch.
Common situations: Middleware that auto-dispatches an init/seed action when instantiated; a logging/analytics middleware that eagerly reports its own startup; migration from redux-thunk where dispatch is called at module top-level while configuring the store; SSR code that dispatches during store assembly.
Related errors
- Actions must be plain objects. Instead, the actual type was:
- Actions may not have an undefined "type" property. You may h
- Action "type" property must be a string. Instead, the actual
- Reducers may not dispatch actions.
- bindActionCreators expected an object or a function, but ins
AI-assisted analysis of reduxjs/redux@3084fc33bb (2026-08-12).
Data as JSON: /api/errors/c7e08a43c4f1a507.
Report an issue: GitHub.