vuejs/vuex · warning

[vuex] error in after action subscribers:

Error message

[vuex] error in after action subscribers: 

What it means

An after action subscriber (subscribeAction after handler) threw inside the promise-resolution path of dispatch. Vuex catches it so the action's result still resolves, warning in development and logging the original error.

Source

Thrown at src/store.js:178

      if (__DEV__) {
        console.warn(`[vuex] error in before action subscribers: `)
        console.error(e)
      }
    }

    const result = entry.length > 1
      ? Promise.all(entry.map(handler => handler(payload)))
      : entry[0](payload)

    return new Promise((resolve, reject) => {
      result.then(res => {
        try {
          this._actionSubscribers
            .filter(sub => sub.after)
            .forEach(sub => sub.after(action, this.state))
        } catch (e) {
          if (__DEV__) {
            console.warn(`[vuex] error in after action subscribers: `)
            console.error(e)
          }
        }
        resolve(res)
      }, error => {
        try {
          this._actionSubscribers
            .filter(sub => sub.error)
            .forEach(sub => sub.error(action, this.state, error))
        } catch (e) {
          if (__DEV__) {
            console.warn(`[vuex] error in error action subscribers: `)
            console.error(e)
          }
        }
        reject(error)
      })
    })

View on GitHub (pinned to bd907467b8)

Solutions

  1. Fix the handler using the error printed by console.error(e)
  2. Add defensive checks/null guards on action.payload inside the handler
  3. Wrap handler logic in try/catch inside the plugin
  4. Update the plugin to the current Vuex subscriber API

Example fix

// before
subscribeAction: { after: (action) => toast(action.payload.message) }
// after
subscribeAction: { after: (action) => { const p = action.payload; if (p && p.message) toast(p.message) } }
Defensive patterns

Strategy: try-catch

Validate before calling

function safeAfterSubscriber(fn) {
  return (action, state) => { try { fn(action, state) } catch (e) { console.warn('after subscriber failed', e) } }
}
// apply when registering: subscribeAction({ after: safeAfterSubscriber(myAfter) })

Type guard

function hasPayloadField(action, field) {
  return Boolean(action && action.payload && field in action.payload)
}

Try / catch

store.subscribeAction({
  after(action, state) {
    try { toast(action.payload?.message) }
    catch (e) { console.warn('[vuex] after subscriber failed', e) }
  }
})

Prevention

When it happens

Trigger: subscribeAction({ after(action, state) { ... } }) throwing when an action resolves — commonly code assuming payload or state shape that changed, or async work that rejects synchronously inside the handler.

Common situations: Success-toast/analytics plugins breaking on actions whose payloads are Errors; subscribers calling router or other side effects that throw; version mismatch where after receives (action, state) but plugin expects options.

Related errors


AI-assisted analysis of vuejs/vuex@bd907467b8 (2026-08-28). Data as JSON: /api/errors/95d9112d7b7b126a. Report an issue: GitHub.