chatwoot/chatwoot · error · Error

error

Error message

error

What it means

In the `deleteHook` action of the integrations store, a failed `IntegrationsAPI.deleteHook(hookId)` is re-wrapped as `throw new Error(error)` (the createHook action just above correctly does `throw error`). Coercion turns object rejections into '[object Object]' and flattens axios errors, discarding response, status and stack. The uiFlags reset is duplicated in both try and catch, which works but is fragile.

Source

Thrown at app/javascript/dashboard/store/modules/integrations.js:135

    commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isCreatingHook: true });
    try {
      const response = await IntegrationsAPI.createHook(hookData);
      commit(types.default.ADD_INTEGRATION_HOOKS, response.data);
      commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isCreatingHook: false });
    } catch (error) {
      commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isCreatingHook: false });
      throw error;
    }
  },
  deleteHook: async ({ commit }, { appId, hookId }) => {
    commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isDeletingHook: true });
    try {
      await IntegrationsAPI.deleteHook(hookId);
      commit(types.default.DELETE_INTEGRATION_HOOKS, { appId, hookId });
      commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isDeletingHook: false });
    } catch (error) {
      commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isDeletingHook: false });
      throw new Error(error);
    }
  },
};

export const mutations = {
  [types.default.SET_INTEGRATIONS_UI_FLAG]($state, uiFlag) {
    $state.uiFlags = { ...$state.uiFlags, ...uiFlag };
  },
  [types.default.SET_INTEGRATIONS]: MutationHelpers.set,
  [types.default.ADD_INTEGRATION]: MutationHelpers.updateAttributes,
  [types.default.DELETE_INTEGRATION]: MutationHelpers.updateAttributes,
  [types.default.ADD_INTEGRATION_HOOKS]: ($state, data) => {
    $state.records = $state.records.map(record => {
      if (record.id === data.app_id) {
        return {
          ...record,
          hooks: [...record.hooks, data],
        };

View on GitHub (pinned to ed230f9bc0)

Solutions

  1. Match the createHook pattern one screen above: `throw error;`
  2. Or wrap with extraction: `throw new Error(error?.response?.data?.message || error?.message || 'Could not delete the hook');`
  3. Catch the dispatch in the integration settings component and show the message.
  4. Optionally move the uiFlags reset into a `finally` block to remove the duplicated commit.

Example fix

// before
} catch (error) {
  commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isDeletingHook: false });
  throw new Error(error);
}

// after
} catch (error) {
  commit(types.default.SET_INTEGRATIONS_UI_FLAG, { isDeletingHook: false });
  throw error;
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  await this.$store.dispatch('integrations/deleteHook', { appId, hookId });
} catch (error) {
  const message = !error?.message || error.message === '[object Object]'
    ? 'Could not delete the hook'
    : error.message;
  this.showAlert(message);
}

Prevention

When it happens

Trigger: Dispatching `integrations/deleteHook` when DELETE /integrations/hooks/:hookId returns 404 (hook already deleted in another tab), 401 (expired session), 403 (missing permission), or the request fails at network level.

Common situations: Stale integration settings page after the hook was removed elsewhere; token expiry mid-session; webhook-capability integrations (Slack/webhooks) being edited concurrently by two admins.

Related errors


AI-assisted analysis of chatwoot/chatwoot@ed230f9bc0 (2026-08-21). Data as JSON: /api/errors/f0365cc3cce8b655. Report an issue: GitHub.