diff --git a/packages/component-faraday-ui/src/submissionRevision/DetailsAndAuthors.js b/packages/component-faraday-ui/src/submissionRevision/DetailsAndAuthors.js
index 9eddd329e20c34a63a8c705791b2be0a46b9e6ae..351585752d1ff1f4f61873070293ece08fd8987e 100644
--- a/packages/component-faraday-ui/src/submissionRevision/DetailsAndAuthors.js
+++ b/packages/component-faraday-ui/src/submissionRevision/DetailsAndAuthors.js
@@ -1,5 +1,5 @@
 import React from 'react'
-import { get } from 'lodash'
+import { get, has } from 'lodash'
 import { Field } from 'redux-form'
 import styled from 'styled-components'
 import { th } from '@pubsweet/ui-toolkit'
@@ -9,6 +9,7 @@ import { Menu, TextField, ValidatedField } from '@pubsweet/ui'
 import {
   Row,
   Item,
+  Text,
   Label,
   Textarea,
   WizardAuthors,
@@ -26,13 +27,14 @@ const DetailsAndAuthors = ({
   collection,
   changeForm,
   formValues,
+  formErrors,
   isAuthorEdit,
   authorsError,
   deleteAuthor,
+  onAuthorEdit,
   manuscriptTypes,
   getTooltipContent,
   isAuthorsFetching,
-  onAuthorEdit,
   ...rest
 }) => (
   <ContextualBox label="Details and Authors" startExpanded transparent>
@@ -74,6 +76,7 @@ const DetailsAndAuthors = ({
         </Item>
       </RowOverrideAlert>
 
+      <Field component={Empty} name="editAuthors" />
       <Field component={Empty} name="authors" />
       <WizardAuthors
         addAuthor={addAuthor}
@@ -89,6 +92,12 @@ const DetailsAndAuthors = ({
         journal={journal}
         onAuthorEdit={onAuthorEdit}
       />
+
+      {has(formErrors, 'editAuthors') && (
+        <Row justify="flex-start" mb={1} mt={1}>
+          <Text error>{get(formErrors, 'editAuthors', '')}</Text>
+        </Row>
+      )}
     </Root>
   </ContextualBox>
 )
diff --git a/packages/component-faraday-ui/src/submissionRevision/ManuscriptFiles.js b/packages/component-faraday-ui/src/submissionRevision/ManuscriptFiles.js
index f14024db2da4badfddbb4394cd6691a33a993f1a..81a19cecb0d1f1d9cab4fcbc30de9e88af545303 100644
--- a/packages/component-faraday-ui/src/submissionRevision/ManuscriptFiles.js
+++ b/packages/component-faraday-ui/src/submissionRevision/ManuscriptFiles.js
@@ -1,5 +1,5 @@
 import React from 'react'
-import { get } from 'lodash'
+import { get, has } from 'lodash'
 import { Field } from 'redux-form'
 import { Icon } from '@pubsweet/ui'
 import styled from 'styled-components'
@@ -20,6 +20,7 @@ const ManuscriptFiles = ({
   filesError,
   previewFile,
   getSignedUrl,
+  formErrors,
 }) => (
   <ContextualBox label="Manuscript Files" startExpanded transparent>
     <Root>
@@ -49,9 +50,9 @@ const ManuscriptFiles = ({
         token={token}
         uploadFile={uploadFile}
       />
-      {filesError && (
+      {has(formErrors, 'files') && (
         <Row justify="flex-start" mt={1}>
-          <Text error>{filesError}</Text>
+          <Text error>{get(formErrors, 'files', '')}</Text>
         </Row>
       )}
     </Root>
diff --git a/packages/component-faraday-ui/src/submissionRevision/SubmitRevision.js b/packages/component-faraday-ui/src/submissionRevision/SubmitRevision.js
index e9b51b1ee1243d82d55cc4a606fe1675fc65377d..6b6c3ae22a1f1c4f665e31ca919ea6c0f810bd02 100644
--- a/packages/component-faraday-ui/src/submissionRevision/SubmitRevision.js
+++ b/packages/component-faraday-ui/src/submissionRevision/SubmitRevision.js
@@ -29,6 +29,7 @@ const SubmitRevision = ({
   deleteResponseFile,
   onAuthorEdit,
   isEditingAuthor,
+  formErrors,
 }) => (
   <ContextualBox highlight label="Submit Revision" mb={2}>
     <Root>
@@ -37,6 +38,7 @@ const SubmitRevision = ({
         changeForm={changeForm}
         collection={collection}
         deleteAuthor={deleteAuthor}
+        formErrors={formErrors}
         fragment={fragment}
         isAuthorEdit={isEditingAuthor}
         manuscriptTypes={journal.manuscriptTypes}
@@ -48,6 +50,7 @@ const SubmitRevision = ({
         collection={collection}
         deleteFile={deleteFile}
         downloadFile={downloadFile}
+        formErrors={formErrors}
         formName="revision"
         fragment={fragment}
         getSignedUrl={getSignedUrl}
diff --git a/packages/component-manuscript/src/submitRevision/utils.js b/packages/component-manuscript/src/submitRevision/utils.js
index ab28ccc47a0564071bd987022aa022f5f3fe20a8..ce3fdc47cfedb55c538e7d865d858ce39e441df4 100644
--- a/packages/component-manuscript/src/submitRevision/utils.js
+++ b/packages/component-manuscript/src/submitRevision/utils.js
@@ -1,23 +1,25 @@
 import { actions } from 'pubsweet-client'
-import { get, debounce, omit, set } from 'lodash'
+import { get, debounce, omit, set, isEqual } from 'lodash'
 import { handleError } from 'pubsweet-component-faraday-ui'
 import { autosaveRequest } from 'pubsweet-component-wizard/src/redux/autosave'
 import { submitRevision } from 'pubsweet-component-wizard/src/redux/conversion'
 
-const parseRevision = (values, fragment) => {
-  const v = omit(values, 'authorForm')
-
-  return {
-    ...fragment,
-    revision: {
-      ...v,
-    },
-  }
-}
+const parseRevision = (values, fragment) => ({
+  ...fragment,
+  revision: {
+    ...values,
+  },
+})
 
 const _onChange = (values, dispatch, { collection, fragment }) => {
-  dispatch(autosaveRequest())
-  dispatch(actions.updateFragment(collection, parseRevision(values, fragment)))
+  const newValues = omit(values, 'editAuthors')
+
+  if (!isEqual(newValues, fragment.revision)) {
+    dispatch(autosaveRequest())
+    dispatch(
+      actions.updateFragment(collection, parseRevision(values, fragment)),
+    )
+  }
 }
 
 export const onChange = debounce(_onChange, 1000, { maxWait: 5000 })
@@ -77,9 +79,17 @@ export const getInitialValues = fragment => ({
   }),
 })
 
-export const validate = ({ responseToReviewers }) => {
+export const validate = ({ editAuthors, files, responseToReviewers }) => {
   const errors = {}
 
+  if (editAuthors) {
+    set(errors, 'editAuthors', 'An unsaved author is being added or edited.')
+  }
+
+  if (get(files, 'manuscripts', []).length === 0) {
+    set(errors, 'files', 'At least one main manuscript file is required.')
+  }
+
   if (!responseToReviewers.content && !responseToReviewers.file) {
     set(
       errors,
diff --git a/packages/component-manuscript/src/submitRevision/withSubmitRevision.js b/packages/component-manuscript/src/submitRevision/withSubmitRevision.js
index 40427a9ceed7074deb17f989c677d9f3224a7279..756551f82f57ab162c74915c3e47fca32701c4c5 100644
--- a/packages/component-manuscript/src/submitRevision/withSubmitRevision.js
+++ b/packages/component-manuscript/src/submitRevision/withSubmitRevision.js
@@ -9,9 +9,13 @@ import {
   withFileDownload,
 } from 'pubsweet-component-faraday-ui'
 import { DragDropContext } from 'react-dnd'
-import { change as changeForm } from 'redux-form'
 import HTML5Backend from 'react-dnd-html5-backend'
 import { withModal } from 'pubsweet-component-modal/src/components'
+import {
+  getFormSyncErrors,
+  setSubmitSucceeded,
+  change as changeForm,
+} from 'redux-form'
 import {
   compose,
   toClass,
@@ -38,22 +42,29 @@ export default compose(
   withFetching,
   withFilePreview,
   withFileDownload,
-  withStateHandlers(
-    { authorEditIndex: null },
-    {
-      onAuthorEdit: () => index => ({
-        authorEditIndex: index,
-      }),
-    },
-  ),
   connect(
     state => ({
+      formErrors:
+        get(state, 'form.revision.submitFailed', false) &&
+        getFormSyncErrors('revision')(state),
       canSubmit: !get(state, 'form.revision.syncErrors'),
       hasFormError:
-        get(state, 'form.revision.syncErrors') &&
-        get(state, 'form.revision.anyTouched', false),
+        get(state, 'form.revision.submitFailed', false) &&
+        get(state, 'form.revision.syncErrors'),
     }),
-    { changeForm },
+    { changeForm, setSubmitSucceeded },
+  ),
+  withStateHandlers(
+    { authorEditIndex: null },
+    {
+      onAuthorEdit: (_, { changeForm, setSubmitSucceeded }) => index => {
+        changeForm('revision', 'editAuthors', !isNull(index))
+        setSubmitSucceeded('revision')
+        return {
+          authorEditIndex: index,
+        }
+      },
+    },
   ),
   withProps(() => ({
     modalKey: 'submitRevision',
@@ -128,6 +139,7 @@ export default compose(
         'deleteAuthor',
         'getSignedUrl',
         'hasFormError',
+        'formErrors',
         'fetchingError',
         'addResponseFile',
         'deleteResponseFile',