diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index ffc38e07f9fa5a5109d53e0005c2ce3c8209c91b..2d74e21c2428bed32fd42da05ae2a6a4450207bb 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -9,6 +9,7 @@ import {defineMessages, injectIntl, intlShape} from 'react-intl';
 import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
 import {openExtensionLibrary} from '../reducers/modals';
 import {
+    getIsError,
     getIsShowingProject
 } from '../reducers/project-state';
 import {setProjectTitle} from '../reducers/project-title';
@@ -63,16 +64,16 @@ class GUI extends React.Component {
         }
     }
     render () {
-        if (this.props.loadingError) {
+        if (this.props.isError) {
             throw new Error(
-                `Failed to load project from server [id=${window.location.hash}]: ${this.props.errorMessage}`);
+                `Failed to load project from server [id=${window.location.hash}]: ${this.props.errStr}`);
         }
         const {
             /* eslint-disable no-unused-vars */
             assetHost,
-            errorMessage,
+            errStr,
             hideIntro,
-            loadingError,
+            isError,
             isShowingProject,
             onUpdateProjectId,
             onUpdateReduxProjectTitle,
@@ -100,14 +101,14 @@ class GUI extends React.Component {
 GUI.propTypes = {
     assetHost: PropTypes.string,
     children: PropTypes.node,
-    errorMessage: PropTypes.string,
+    errStr: PropTypes.string,
     fetchingProject: PropTypes.bool,
     hideIntro: PropTypes.bool,
     importInfoVisible: PropTypes.bool,
+    isError: PropTypes.bool,
     intl: intlShape,
     isLoading: PropTypes.bool,
     isShowingProject: PropTypes.bool,
-    loadingError: PropTypes.bool,
     loadingStateVisible: PropTypes.bool,
     onChangeProjectInfo: PropTypes.func,
     onSeeCommunity: PropTypes.func,
@@ -135,7 +136,9 @@ const mapStateToProps = (state, ownProps) => {
         cardsVisible: state.scratchGui.cards.visible,
         costumeLibraryVisible: state.scratchGui.modals.costumeLibrary,
         costumesTabVisible: state.scratchGui.editorTab.activeTabIndex === COSTUMES_TAB_INDEX,
+        errStr: state.scratchGui.projectState.errStr,
         importInfoVisible: state.scratchGui.modals.importInfo,
+        isError: getIsError(loadingState),
         isPlayerOnly: state.scratchGui.mode.isPlayerOnly,
         isRtl: state.locales.isRtl,
         isShowingProject: getIsShowingProject(loadingState),
diff --git a/src/lib/project-fetcher-hoc.jsx b/src/lib/project-fetcher-hoc.jsx
index 6a29cf75db29a5ecef8e1ea6ccae618f72cc2dbf..20fb80602e771d7223aa533079b955d25661b3ea 100644
--- a/src/lib/project-fetcher-hoc.jsx
+++ b/src/lib/project-fetcher-hoc.jsx
@@ -8,6 +8,7 @@ import {
     LoadingStates,
     defaultProjectId,
     getIsFetchingWithId,
+    onError,
     onFetchedProjectData,
     setProjectId
 } from '../reducers/project-state';
@@ -74,6 +75,7 @@ const ProjectFetcherHOC = function (WrappedComponent) {
                     }
                 })
                 .catch(err => {
+                    this.props.onError(`Saving the project failed with error: ${err}`);
                     log.error(err);
                 });
         }
@@ -106,6 +108,7 @@ const ProjectFetcherHOC = function (WrappedComponent) {
         intl: intlShape.isRequired,
         isFetchingWithId: PropTypes.bool,
         loadingState: PropTypes.oneOf(LoadingStates),
+        onError: PropTypes.func,
         onFetchedProjectData: PropTypes.func,
         projectHost: PropTypes.string,
         projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -123,6 +126,7 @@ const ProjectFetcherHOC = function (WrappedComponent) {
         reduxProjectId: state.scratchGui.projectState.projectId
     });
     const mapDispatchToProps = dispatch => ({
+        onError: errStr => dispatch(onError(errStr)),
         onFetchedProjectData: (projectData, loadingState) =>
             dispatch(onFetchedProjectData(projectData, loadingState)),
         setProjectId: projectId => dispatch(setProjectId(projectId))
diff --git a/src/lib/vm-manager-hoc.jsx b/src/lib/vm-manager-hoc.jsx
index cfc80bc97e066e0504a1fa5119bb81f8a526d355..20271706d4a584b5a34f598dd267726bab3e410c 100644
--- a/src/lib/vm-manager-hoc.jsx
+++ b/src/lib/vm-manager-hoc.jsx
@@ -8,6 +8,7 @@ import AudioEngine from 'scratch-audio';
 
 import {
     LoadingStates,
+    onError,
     onLoadedProject,
     getIsLoadingWithId
 } from '../reducers/project-state';
@@ -24,10 +25,6 @@ const vmManagerHOC = function (WrappedComponent) {
             bindAll(this, [
                 'loadProject'
             ]);
-            this.state = {
-                loadingError: false,
-                errorMessage: ''
-            };
         }
         componentDidMount () {
             if (this.props.vm.initialized) return;
@@ -51,9 +48,7 @@ const vmManagerHOC = function (WrappedComponent) {
                     this.props.onLoadedProject(this.props.loadingState, this.props.canSave);
                 })
                 .catch(e => {
-                    // Need to catch this error and update component state so that
-                    // error page gets rendered if project failed to load
-                    this.setState({loadingError: true, errorMessage: e});
+                    this.props.onError(e);
                 });
         }
         render () {
@@ -71,9 +66,7 @@ const vmManagerHOC = function (WrappedComponent) {
             } = this.props;
             return (
                 <WrappedComponent
-                    errorMessage={this.state.errorMessage}
                     isLoading={isLoadingWithIdProp}
-                    loadingError={this.state.loadingError}
                     vm={vm}
                     {...componentProps}
                 />
@@ -86,6 +79,7 @@ const vmManagerHOC = function (WrappedComponent) {
         fontsLoaded: PropTypes.bool,
         isLoadingWithId: PropTypes.bool,
         loadingState: PropTypes.oneOf(LoadingStates),
+        onError: PropTypes.func,
         onLoadedProject: PropTypes.func,
         projectData: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
         projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -103,6 +97,7 @@ const vmManagerHOC = function (WrappedComponent) {
     };
 
     const mapDispatchToProps = dispatch => ({
+        onError: errStr => dispatch(onError(errStr)),
         onLoadedProject: (loadingState, canSave) =>
             dispatch(onLoadedProject(loadingState, canSave))
     });
diff --git a/src/reducers/project-state.js b/src/reducers/project-state.js
index de171edc5df734fb35e2d35c19e5f96a9271a000..1b80fd3e481ce92c6b55124273489dc92f7df41d 100644
--- a/src/reducers/project-state.js
+++ b/src/reducers/project-state.js
@@ -65,6 +65,9 @@ const getIsShowingWithId = loadingState => (
 const getIsShowingWithoutId = loadingState => (
     loadingState === LoadingState.SHOWING_WITHOUT_ID
 );
+const getIsError = loadingState => (
+    loadingState === LoadingState.ERROR
+);
 
 const initialState = {
     errStr: null,
@@ -326,6 +329,7 @@ export {
     createProject,
     defaultProjectId,
     getIsCreating,
+    getIsError,
     getIsFetchingWithoutId,
     getIsFetchingWithId,
     getIsLoadingWithId,