diff --git a/src/reducers/project-state.js b/src/reducers/project-state.js
index 91e51bbe48e6b8fa1c0cb1b254cbce7350f4a246..76955d589d561df8d7710167aaf9fc954e21a213 100644
--- a/src/reducers/project-state.js
+++ b/src/reducers/project-state.js
@@ -17,7 +17,7 @@ const START_AUTO_UPDATING = 'scratch-gui/project-state/START_AUTO_UPDATING';
 const START_CREATING_NEW = 'scratch-gui/project-state/START_CREATING_NEW';
 const START_ERROR = 'scratch-gui/project-state/START_ERROR';
 const START_FETCHING_NEW = 'scratch-gui/project-state/START_FETCHING_NEW';
-const START_LOADING_VM_FILE_UPLOAD = 'scratch-gui/project-state/START_LOADING_FILE_UPLOAD';
+const START_LOADING_VM_FILE_UPLOAD = 'scratch-gui/project-state/START_LOADING_VM_FILE_UPLOAD';
 const START_MANUAL_UPDATING = 'scratch-gui/project-state/START_MANUAL_UPDATING';
 const START_REMIXING = 'scratch-gui/project-state/START_REMIXING';
 const START_UPDATING_BEFORE_CREATING_COPY = 'scratch-gui/project-state/START_UPDATING_BEFORE_CREATING_COPY';
@@ -413,32 +413,31 @@ const onFetchedProjectData = (projectData, loadingState) => {
 };
 
 const onLoadedProject = (loadingState, canSave, success) => {
-    if (success) {
-        switch (loadingState) {
-        case LoadingState.LOADING_VM_WITH_ID:
-            return {
-                type: DONE_LOADING_VM_WITH_ID
-            };
-        case LoadingState.LOADING_VM_FILE_UPLOAD:
+    switch (loadingState) {
+    case LoadingState.LOADING_VM_WITH_ID:
+        if (success) {
+            return {type: DONE_LOADING_VM_WITH_ID};
+        }
+        // failed to load project; just keep showing current project
+        return {type: RETURN_TO_SHOWING};
+    case LoadingState.LOADING_VM_FILE_UPLOAD:
+        if (success) {
             if (canSave) {
-                return {
-                    type: DONE_LOADING_VM_TO_SAVE
-                };
+                return {type: DONE_LOADING_VM_TO_SAVE};
             }
-            return {
-                type: DONE_LOADING_VM_WITHOUT_ID
-            };
-        case LoadingState.LOADING_VM_NEW_DEFAULT:
-            return {
-                type: DONE_LOADING_VM_WITHOUT_ID
-            };
-        default:
-            return;
+            return {type: DONE_LOADING_VM_WITHOUT_ID};
         }
+        // failed to load project; just keep showing current project
+        return {type: RETURN_TO_SHOWING};
+    case LoadingState.LOADING_VM_NEW_DEFAULT:
+        if (success) {
+            return {type: DONE_LOADING_VM_WITHOUT_ID};
+        }
+        // failed to load default project; show error
+        return {type: START_ERROR};
+    default:
+        return;
     }
-    return {
-        type: RETURN_TO_SHOWING
-    };
 };
 
 const doneUpdatingProject = loadingState => {
diff --git a/test/unit/reducers/project-state-reducer.test.js b/test/unit/reducers/project-state-reducer.test.js
index 2683c5beec159d4a08a86b003f15905071b82648..faf208bf4341b8114df38fd8e6543ecb430b8724 100644
--- a/test/unit/reducers/project-state-reducer.test.js
+++ b/test/unit/reducers/project-state-reducer.test.js
@@ -92,99 +92,181 @@ test('onFetchedProjectData new loads project data into vm', () => {
     expect(resultState.projectData).toBe('1010101');
 });
 
-test('onLoadedProject upload, with canSave false, shows without id', () => {
+// onLoadedProject: LOADING_VM_WITH_ID
+
+test('onLoadedProject(LOADING_VM_WITH_ID, true, true) results in state SHOWING_WITH_ID', () => {
     const initialState = {
-        loadingState: LoadingState.LOADING_VM_FILE_UPLOAD
+        projectId: '100',
+        loadingState: LoadingState.LOADING_VM_WITH_ID
+    };
+    const action = onLoadedProject(initialState.loadingState, true, true);
+    const resultState = projectStateReducer(initialState, action);
+    expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('100');
+});
+
+test('onLoadedProject(LOADING_VM_WITH_ID, false, true) results in state SHOWING_WITH_ID', () => {
+    const initialState = {
+        projectId: '100',
+        loadingState: LoadingState.LOADING_VM_WITH_ID
     };
     const action = onLoadedProject(initialState.loadingState, false, true);
     const resultState = projectStateReducer(initialState, action);
+    expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('100');
+});
+
+// case where we started out viewing a project with a projectId, then
+// started to load another project; but loading fails. We go back to
+// showing the original project.
+test('onLoadedProject(LOADING_VM_WITH_ID, false, false), with project id, ' +
+    'results in state SHOWING_WITH_ID', () => {
+    const initialState = {
+        projectId: '100',
+        loadingState: LoadingState.LOADING_VM_WITH_ID
+    };
+    const action = onLoadedProject(initialState.loadingState, false, false);
+    const resultState = projectStateReducer(initialState, action);
+    expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('100');
+});
+
+// case where we started out viewing a project with default projectId, then
+// started to load one with an id, such as in standalone mode when user adds
+// '#PROJECT_ID_NUMBER' to the URI; but loading fails. We go back to
+// showing the original project.
+test('onLoadedProject(LOADING_VM_WITH_ID, false, false), with no project id, ' +
+    'results in state SHOWING_WITHOUT_ID', () => {
+    const initialState = {
+        projectId: '0',
+        loadingState: LoadingState.LOADING_VM_WITH_ID
+    };
+    const action = onLoadedProject(initialState.loadingState, false, false);
+    const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('onLoadedProject upload, with canSave true, prepares to save', () => {
+// onLoadedProject: LOADING_VM_FILE_UPLOAD
+
+test('onLoadedProject(LOADING_VM_FILE_UPLOAD, true, true) prepares to save', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.LOADING_VM_FILE_UPLOAD
     };
     const action = onLoadedProject(initialState.loadingState, true, true);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.AUTO_UPDATING);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('onLoadedProject with id shows with id', () => {
+test('onLoadedProject(LOADING_VM_FILE_UPLOAD, false, true) results in state SHOWING_WITHOUT_ID', () => {
     const initialState = {
-        loadingState: LoadingState.LOADING_VM_WITH_ID
+        projectId: '0',
+        loadingState: LoadingState.LOADING_VM_FILE_UPLOAD
     };
-    const action = onLoadedProject(initialState.loadingState, true, true);
+    const action = onLoadedProject(initialState.loadingState, false, true);
+    const resultState = projectStateReducer(initialState, action);
+    expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
+});
+
+test('onLoadedProject(LOADING_VM_FILE_UPLOAD, false, false), when we know project id, ' +
+    'results in state SHOWING_WITH_ID', () => {
+    const initialState = {
+        projectId: '100',
+        loadingState: LoadingState.LOADING_VM_FILE_UPLOAD
+    };
+    const action = onLoadedProject(initialState.loadingState, false, false);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('onLoadedProject new shows without id', () => {
+test('onLoadedProject(LOADING_VM_FILE_UPLOAD, false, false), when we ' +
+    'don\'t know project id, results in state SHOWING_WITHOUT_ID', () => {
     const initialState = {
-        loadingState: LoadingState.LOADING_VM_NEW_DEFAULT
+        projectId: '0',
+        loadingState: LoadingState.LOADING_VM_FILE_UPLOAD
     };
-    const action = onLoadedProject(initialState.loadingState, false, true);
+    const action = onLoadedProject(initialState.loadingState, false, false);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('onLoadedProject new, to save shows without id', () => {
+// onLoadedProject: LOADING_VM_NEW_DEFAULT
+
+test('onLoadedProject(LOADING_VM_NEW_DEFAULT, true, true) results in state SHOWING_WITHOUT_ID', () => {
     const initialState = {
+        projectId: '0',
         loadingState: LoadingState.LOADING_VM_NEW_DEFAULT
     };
     const action = onLoadedProject(initialState.loadingState, true, true);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('onLoadedProject with success false, no project id, shows without id', () => {
+test('onLoadedProject(LOADING_VM_NEW_DEFAULT, false, true) results in state SHOWING_WITHOUT_ID', () => {
     const initialState = {
-        loadingState: LoadingState.LOADING_VM_WITH_ID,
-        projectId: null
+        projectId: '0',
+        loadingState: LoadingState.LOADING_VM_NEW_DEFAULT
     };
-    const action = onLoadedProject(initialState.loadingState, false, false);
+    const action = onLoadedProject(initialState.loadingState, false, true);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('onLoadedProject with success false, valid project id, shows with id', () => {
+test('onLoadedProject(LOADING_VM_NEW_DEFAULT, false, false) results in ERROR state', () => {
     const initialState = {
-        loadingState: LoadingState.LOADING_VM_WITH_ID,
-        projectId: '12345'
+        projectId: '0',
+        loadingState: LoadingState.LOADING_VM_NEW_DEFAULT
     };
     const action = onLoadedProject(initialState.loadingState, false, false);
     const resultState = projectStateReducer(initialState, action);
-    expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.loadingState).toBe(LoadingState.ERROR);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('doneUpdatingProject with id shows with id', () => {
+// doneUpdatingProject
+
+test('doneUpdatingProject with id results in state SHOWING_WITH_ID', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.MANUAL_UPDATING
     };
     const action = doneUpdatingProject(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('doneUpdatingProject with id, before copy, creates copy', () => {
+test('doneUpdatingProject with id, before copy occurs, results in state CREATING_COPY', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.UPDATING_BEFORE_COPY
     };
     const action = doneUpdatingProject(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.CREATING_COPY);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('doneUpdatingProject with id, before new, fetches default project', () => {
+test('doneUpdatingProject with id, before new, results in state FETCHING_NEW_DEFAULT', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.UPDATING_BEFORE_NEW
     };
     const action = doneUpdatingProject(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.FETCHING_NEW_DEFAULT);
+    expect(resultState.projectId).toBe('0'); // resets id
 });
 
-test('setProjectId, with same id as before, should show with id, not fetch', () => {
+test('calling setProjectId, using with same id as already showing, ' +
+    'results in state SHOWING_WITH_ID', () => {
     const initialState = {
         projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
@@ -195,7 +277,8 @@ test('setProjectId, with same id as before, should show with id, not fetch', ()
     expect(resultState.projectId).toBe('100');
 });
 
-test('setProjectId, with different id as before, should fetch with id, not show with id', () => {
+test('calling setProjectId, using different id from project already showing, ' +
+    'results in state FETCHING_WITH_ID', () => {
     const initialState = {
         projectId: 99,
         loadingState: LoadingState.SHOWING_WITH_ID
@@ -206,7 +289,8 @@ test('setProjectId, with different id as before, should fetch with id, not show
     expect(resultState.projectId).toBe('100');
 });
 
-test('setProjectId, with same id as before, but not same type, should fetch because not ===', () => {
+test('setProjectId, with same id as before, but not same type, ' +
+    'results in FETCHING_WITH_ID because the two projectIds are not strictly equal', () => {
     const initialState = {
         projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
@@ -217,85 +301,104 @@ test('setProjectId, with same id as before, but not same type, should fetch beca
     expect(resultState.projectId).toBe(100);
 });
 
-test('requestNewProject, when can\'t create new, should fetch default project without id', () => {
+test('requestNewProject, when can\'t create/save, results in FETCHING_NEW_DEFAULT', () => {
     const initialState = {
+        projectId: '0',
         loadingState: LoadingState.SHOWING_WITHOUT_ID
     };
     const action = requestNewProject(false);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.FETCHING_NEW_DEFAULT);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('requestNewProject, when can create new, should save and prepare to fetch default project', () => {
+test('requestNewProject, when can create/save, results in UPDATING_BEFORE_NEW ' +
+    '(in order to save before fetching default project)', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = requestNewProject(true);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.UPDATING_BEFORE_NEW);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('requestProjectUpload when project not loaded should load', () => {
+test('requestProjectUpload when project not loaded results in state LOADING_VM_FILE_UPLOAD', () => {
     const initialState = {
+        projectId: null,
         loadingState: LoadingState.NOT_LOADED
     };
     const action = requestProjectUpload(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.LOADING_VM_FILE_UPLOAD);
+    expect(resultState.projectId).toBe(null);
 });
 
-test('requestProjectUpload when showing project with id should load', () => {
+test('requestProjectUpload when showing project with id results in state LOADING_VM_FILE_UPLOAD', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = requestProjectUpload(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.LOADING_VM_FILE_UPLOAD);
+    expect(resultState.projectId).toBe('100');
 });
 
-test('requestProjectUpload when showing project without id should load', () => {
+test('requestProjectUpload when showing project without id results in state LOADING_VM_FILE_UPLOAD', () => {
     const initialState = {
+        projectId: null,
         loadingState: LoadingState.SHOWING_WITHOUT_ID
     };
     const action = requestProjectUpload(initialState.loadingState);
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.LOADING_VM_FILE_UPLOAD);
+    expect(resultState.projectId).toBe(null);
 });
 
 test('manualUpdateProject should prepare to update', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = manualUpdateProject();
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.MANUAL_UPDATING);
+    expect(resultState.projectId).toBe('100');
 });
 
 test('autoUpdateProject should prepare to update', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = autoUpdateProject();
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.AUTO_UPDATING);
+    expect(resultState.projectId).toBe('100');
 });
 
 test('saveProjectAsCopy should save, before preparing to save as a copy', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = saveProjectAsCopy();
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.UPDATING_BEFORE_COPY);
+    expect(resultState.projectId).toBe('100');
 });
 
 test('remixProject should prepare to remix', () => {
     const initialState = {
+        projectId: '100',
         loadingState: LoadingState.SHOWING_WITH_ID
     };
     const action = remixProject();
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.REMIXING);
+    expect(resultState.projectId).toBe('100');
 });
 
 test('projectError from various states should show error', () => {
@@ -314,11 +417,13 @@ test('projectError from various states should show error', () => {
     for (const startState of startStates) {
         const initialState = {
             error: null,
+            projectId: '100',
             loadingState: startState
         };
         const action = projectError('Error string');
         const resultState = projectStateReducer(initialState, action);
         expect(resultState.error).toEqual('Error string');
+        expect(resultState.projectId).toBe('100');
     }
 });
 
@@ -332,11 +437,13 @@ test('fatal projectError should show error state', () => {
     for (const startState of startStates) {
         const initialState = {
             error: null,
+            projectId: '100',
             loadingState: startState
         };
         const action = projectError('Error string');
         const resultState = projectStateReducer(initialState, action);
         expect(resultState.loadingState).toBe(LoadingState.ERROR);
+        expect(resultState.projectId).toBe('100');
     }
 });
 
@@ -351,15 +458,18 @@ test('non-fatal projectError should show normal state', () => {
     for (const startState of startStates) {
         const initialState = {
             error: null,
+            projectId: '100',
             loadingState: startState
         };
         const action = projectError('Error string');
         const resultState = projectStateReducer(initialState, action);
         expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+        expect(resultState.projectId).toBe('100');
     }
 });
 
-test('projectError when creating new while viewing project with id should show project with id', () => {
+test('projectError when creating new while viewing project with id should ' +
+    'go back to state SHOWING_WITH_ID', () => {
     const initialState = {
         error: null,
         loadingState: LoadingState.CREATING_NEW,
@@ -368,9 +478,11 @@ test('projectError when creating new while viewing project with id should show p
     const action = projectError('Error string');
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITH_ID);
+    expect(resultState.projectId).toBe('12345');
 });
 
-test('projectError when creating new while logged out, looking at default project should show default project', () => {
+test('projectError when creating new while logged out, looking at default project ' +
+    'should go back to state SHOWING_WITHOUT_ID', () => {
     const initialState = {
         error: null,
         loadingState: LoadingState.CREATING_NEW,
@@ -379,15 +491,19 @@ test('projectError when creating new while logged out, looking at default projec
     const action = projectError('Error string');
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.SHOWING_WITHOUT_ID);
+    expect(resultState.projectId).toBe('0');
 });
 
-test('projectError from showing project should show error', () => {
+test('projectError encountered while in state FETCHING_WITH_ID results in ' +
+    'ERROR state', () => {
     const initialState = {
         error: null,
+        projectId: null,
         loadingState: LoadingState.FETCHING_WITH_ID
     };
     const action = projectError('Error string');
     const resultState = projectStateReducer(initialState, action);
     expect(resultState.loadingState).toBe(LoadingState.ERROR);
+    expect(resultState.projectId).toBe(null);
     expect(resultState.error).toEqual('Error string');
 });
diff --git a/test/unit/util/project-saver-hoc.test.jsx b/test/unit/util/project-saver-hoc.test.jsx
index 0ec3190bf773fdf74aa6cc39c671b27e0df32beb..f5ac7b680e669c758c6af021643be10fc4d35692 100644
--- a/test/unit/util/project-saver-hoc.test.jsx
+++ b/test/unit/util/project-saver-hoc.test.jsx
@@ -56,7 +56,7 @@ describe('projectSaverHOC', () => {
         expect(mockedUpdateProject).toHaveBeenCalled();
     });
 
-    test('if canSave is alreatdy true and we show a project with an id, project will NOT be saved', () => {
+    test('if canSave is already true and we show a project with an id, project will NOT be saved', () => {
         const mockedSaveProject = jest.fn();
         const Component = () => <div />;
         const WrappedComponent = projectSaverHOC(Component);