vuejs/vuex · warning

[vuex] error in before action subscribers:

Error message

[vuex] error in before action subscribers: 

What it means

A before action subscriber (registered via subscribeAction with a before handler or object form) threw synchronously during dispatch. Vuex catches it so dispatch continues, logging a warning plus the original error in development.

Source

Thrown at src/store.js:161

    } = unifyObjectStyle(_type, _payload)

    const action = { type, payload }
    const entry = this._actions[type]
    if (!entry) {
      if (__DEV__) {
        console.error(`[vuex] unknown action type: ${type}`)
      }
      return
    }

    try {
      this._actionSubscribers
        .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
        .filter(sub => sub.before)
        .forEach(sub => sub.before(action, this.state))
    } catch (e) {
      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)

View on GitHub (pinned to bd907467b8)

Solutions

  1. Wrap subscriber bodies in their own try/catch and log context
  2. Fix the throwing logic shown by the accompanying console.error(e)
  3. Check subscriber argument order (action, state) matches current Vuex version
  4. Isolate subscribers by removing them one at a time to find the culprit plugin

Example fix

// before
store.subscribeAction({ before(action, state) { log(action.payload.detail) } })
// after
store.subscribeAction({ before(action, state) { try { log(action.payload?.detail) } catch (err) { console.warn('subscriber failed', err) } } })
Defensive patterns

Strategy: try-catch

Validate before calling

function safeSubscriber(fn) {
  return (...args) => { try { return fn(...args) } catch (e) { console.warn('action subscriber error', e) } }
}
store.subscribeAction({ before: safeSubscriber((action, state) => { /* ... */ }) })

Type guard

function isActionSubscriber(sub) {
  return typeof sub === 'function' || (sub && ['before','after','error'].some(k => typeof sub[k] === 'function'))
}

Try / catch

store.subscribeAction({
  before(action, state) {
    try { analytics.track(action.type, action.payload) }
    catch (e) { console.warn('[vuex] before subscriber failed', e) }
  }
})

Prevention

When it happens

Trigger: subscribeAction({ before(action, state) { ... } }) where the handler throws — e.g. accessing a property of undefined state, calling a removed API, or a logging/analytics subscriber with a bug.

Common situations: Analytics/log plugins written for an older Vuex signature (payload/order changed); plugin reading state fields removed after refactor; subscriber calling store methods re-entrantly.

Related errors


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