diff --git a/frontend/src/app.js b/frontend/src/app.js
index 5738bfd85562ba22c2b6429d82ddf122ccb46f7d..fbf5542a7e247083b7752762a03b4d126c4e1852 100644
--- a/frontend/src/app.js
+++ b/frontend/src/app.js
@@ -41,6 +41,7 @@ import { reducer as form } from "redux-form";
 import * as datamodel from 'metabase/admin/datamodel/reducers';
 import questions from 'metabase/questions/questions';
 import labels from 'metabase/questions/labels';
+import undo from 'metabase/questions/undo';
 
 import { registerAnalyticsClickListener } from "metabase/lib/analytics";
 
@@ -83,6 +84,7 @@ Metabase.config(['$routeProvider', '$locationProvider', function($routeProvider,
                     datamodel: combineReducers(datamodel),
                     questions,
                     labels,
+                    undo,
                     form,
                     router,
                     user: (state = null) => state
diff --git a/frontend/src/questions/containers/UndoListing.jsx b/frontend/src/questions/containers/UndoListing.jsx
index f7bf50408faa95c02ff8e334af557f794afeafe9..2ff7f4b28f218a5c8ad82b6e361ed3eb38dcbd8a 100644
--- a/frontend/src/questions/containers/UndoListing.jsx
+++ b/frontend/src/questions/containers/UndoListing.jsx
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
 
 import S from "./UndoListing.css";
 
-import { dismissUndo, performUndo } from "../questions";
+import { dismissUndo, performUndo } from "../undo";
 import { getUndos } from "../selectors";
 
 import Icon from "metabase/components/Icon";
diff --git a/frontend/src/questions/questions.js b/frontend/src/questions/questions.js
index 8a46960ba86c8cb4236fa97f9b26223764624502..95de4867938b8ba2aae1107fdf746bc9235b82c9 100644
--- a/frontend/src/questions/questions.js
+++ b/frontend/src/questions/questions.js
@@ -6,6 +6,7 @@ import i from "icepick";
 import _ from "underscore";
 
 import { getSelectedEntities } from "./selectors";
+import { addUndo } from "./undo";
 
 const card = new Schema('cards');
 const label = new Schema('labels');
@@ -22,9 +23,6 @@ const SET_ALL_SELECTED = 'metabase/questions/SET_ALL_SELECTED';
 const SET_FAVORITED = 'metabase/questions/SET_FAVORITED';
 const SET_ARCHIVED = 'metabase/questions/SET_ARCHIVED';
 const SET_LABELED = 'metabase/questions/SET_LABELED';
-const ADD_UNDO = 'metabase/questions/ADD_UNDO';
-const DISMISS_UNDO = 'metabase/questions/DISMISS_UNDO';
-const PERFORM_UNDO = 'metabase/questions/PERFORM_UNDO';
 
 export const selectSection = createThunkAction(SELECT_SECTION, (section = "all", slug = null, type = "cards") => {
     return async (dispatch, getState) => {
@@ -75,24 +73,26 @@ export const setFavorited = createThunkAction(SET_FAVORITED, (cardId, favorited)
     }
 });
 
-export const setArchived = createThunkAction(SET_ARCHIVED, (cardId, archived, showUndo = true) => {
+export const setArchived = createThunkAction(SET_ARCHIVED, (cardId, archived, undoable = true) => {
     return async (dispatch, getState) => {
         if (cardId == null) {
             // bulk archive
             let selected = getSelectedEntities(getState()).filter(item => item.archived !== archived);
             selected.map(item => dispatch(setArchived(item.id, archived, false)));
             // TODO: errors
-            dispatch(addUndo(
-                selected.length + " question were " + (archived ? "archived" : "unarchived"),
-                selected.map(item => setArchived(cardId, !archived, false))
-            ));
+            if (undoable) {
+                dispatch(addUndo(
+                    selected.length + " question were " + (archived ? "archived" : "unarchived"),
+                    selected.map(item => setArchived(item.id, !archived, false))
+                ));
+            }
         } else {
             let card = {
                 ...getState().questions.entities.cards[cardId],
                 archived: archived
             };
             let response = await CardApi.update(card);
-            if (showUndo) {
+            if (undoable) {
                 dispatch(addUndo("Question was " + (archived ? "archived" : "unarchived"), [
                     setArchived(cardId, !archived, false)
                 ]));
@@ -129,30 +129,6 @@ export const setSearchText = createAction(SET_SEARCH_TEXT);
 export const setItemSelected = createAction(SET_ITEM_SELECTED);
 export const setAllSelected = createAction(SET_ALL_SELECTED);
 
-let nextUndoId = 0;
-
-export const addUndo = createThunkAction(ADD_UNDO, (message, actions) => {
-    return (dispatch, getState) => {
-        let id = nextUndoId++;
-        setTimeout(() => dispatch(dismissUndo(id)), 5000);
-        return { id, message, actions };
-    };
-});
-
-export const dismissUndo = createAction(DISMISS_UNDO);
-
-export const performUndo = createThunkAction(PERFORM_UNDO, (undoId) => {
-    return (dispatch, getState) => {
-        let undo = _.findWhere(getState().questions.undos, { id: undoId });
-        if (undo) {
-            undo.actions.map(action =>
-                dispatch(action)
-            );
-            dispatch(dismissUndo(undoId));
-        }
-    };
-});
-
 const initialState = {
     entities: {},
     type: "cards",
@@ -187,7 +163,7 @@ export default function(state = initialState, { type, payload, error }) {
         case SET_FAVORITED:
             if (error) {
                 return state;
-            } else {
+            } else if (payload && payload.id != null) {
                 state = i.assocIn(state, ["entities", "cards", payload.id], {
                     ...state.entities.cards[payload.id],
                     ...payload
@@ -199,10 +175,11 @@ export default function(state = initialState, { type, payload, error }) {
                 }
                 return state;
             }
+            return state;
         case SET_ARCHIVED:
             if (error) {
                 return state;
-            } else {
+            } else if (payload && payload.id != null) {
                 state = i.assocIn(state, ["entities", "cards", payload.id], {
                     ...state.entities.cards[payload.id],
                     ...payload
@@ -216,13 +193,11 @@ export default function(state = initialState, { type, payload, error }) {
                 }
                 return state;
             }
+            return state;
         case SET_LABELED:
             if (error) {
                 return state;
-            } else {
-                if (payload.id == null) {
-                    return state;
-                }
+            } else if (payload && payload.id != null) {
                 state = i.assocIn(state, ["entities", "cards", payload.id], {
                     ...state.entities.cards[payload.id],
                     ...payload
@@ -234,10 +209,7 @@ export default function(state = initialState, { type, payload, error }) {
                 }
                 return state;
             }
-        case ADD_UNDO:
-            return { ...state, undos: state.undos.concat(payload) };
-        case DISMISS_UNDO:
-            return { ...state, undos: state.undos.filter(undo => undo.id !== payload) };
+            return state;
         default:
             return state;
     }
diff --git a/frontend/src/questions/selectors.js b/frontend/src/questions/selectors.js
index 70a9cd35f5a730e66982d6e55a67dc22e6fc2969..c366df30fd156a7744a0f0cc42c26f8be64f02e2 100644
--- a/frontend/src/questions/selectors.js
+++ b/frontend/src/questions/selectors.js
@@ -161,4 +161,4 @@ export const getSectionName = createSelector(
     }
 );
 
-export const getUndos = (state) => state.questions.undos;
+export const getUndos = (state) => state.undo;
diff --git a/frontend/src/questions/undo.js b/frontend/src/questions/undo.js
new file mode 100644
index 0000000000000000000000000000000000000000..25cc917b5f5a4956ffb62b38e477d0e59cc36e46
--- /dev/null
+++ b/frontend/src/questions/undo.js
@@ -0,0 +1,51 @@
+
+import { createAction, createThunkAction } from "metabase/lib/redux";
+
+import _ from "underscore";
+
+const ADD_UNDO = 'metabase/questions/ADD_UNDO';
+const DISMISS_UNDO = 'metabase/questions/DISMISS_UNDO';
+const PERFORM_UNDO = 'metabase/questions/PERFORM_UNDO';
+
+let nextUndoId = 0;
+
+export const addUndo = createThunkAction(ADD_UNDO, (message, actions) => {
+    return (dispatch, getState) => {
+        let id = nextUndoId++;
+        setTimeout(() => dispatch(dismissUndo(id)), 5000);
+        return { id, message, actions };
+    };
+});
+
+export const dismissUndo = createAction(DISMISS_UNDO);
+
+export const performUndo = createThunkAction(PERFORM_UNDO, (undoId) => {
+    return (dispatch, getState) => {
+        let undo = _.findWhere(getState().undo, { id: undoId });
+        console.log("undo", undo)
+        if (undo) {
+            undo.actions.map(action =>
+                dispatch(action)
+            );
+            dispatch(dismissUndo(undoId));
+        }
+    };
+});
+
+export default function(state = [], { type, payload, error }) {
+    switch (type) {
+        case ADD_UNDO:
+            if (error) {
+                console.warn("ADD_UNDO", payload);
+                return state;
+            }
+            return state.concat(payload);
+        case DISMISS_UNDO:
+            if (error) {
+                console.warn("DISMISS_UNDO", payload);
+                return state;
+            }
+            return state.filter(undo => undo.id !== payload);
+    }
+    return state;
+}