Index: ticket/web_ui.py
===================================================================
--- ticket/web_ui.py	(revision 6813)
+++ ticket/web_ui.py	(working copy)
@@ -431,7 +431,6 @@
                 return self._render_diff(req, ticket, data, text_fields)
         elif req.method == 'POST': # 'Preview' or 'Submit'
             self._populate(req, ticket)
-            valid = self._validate_ticket(req, ticket)
 
             # Do any action on the ticket?
             actions = TicketSystem(self.env).get_available_actions(
@@ -441,6 +440,7 @@
                 # (this should never happen in normal situations)
             field_changes, problems = self.get_ticket_changes(req, ticket,
                                                               action)
+            valid = True
             if problems:
                 valid = False
                 for problem in problems:
@@ -451,13 +451,24 @@
                                     tag.pre('[trac]\nworkflow = ...\n'),
                                     tag.p('in your ', tag.tt('trac.ini'), '.'))
                                 )
-            if 'preview' not in req.args:
-                if valid:
-                    self._apply_ticket_changes(ticket, field_changes)
-                    # redirected if successful
-                    self._do_save(req, ticket, action)
-                # else fall through in a preview
-                req.args['preview'] = True
+            if valid:
+                ## I can't work out how to copy a whole ticket so I only copy
+                ## the relevent bits that could change when calling _apply_ticket_changes.
+                ## There is almost certainly a better way to do this!!!
+                from copy import copy
+                workflow_ticket = copy(ticket)
+                workflow_ticket.values = copy(ticket.values)
+                workflow_ticket.old = copy(ticket._old)
+                self._apply_ticket_changes(workflow_ticket, field_changes)
+                # redirected if successful
+                if self._validate_ticket(req, workflow_ticket):
+                    if 'preview' not in req.args:
+                        self._do_save(req, workflow_ticket, action)
+                        # No need to copy workflow_ticket back to ticket as
+                        # _do_save will redirect if all is well :)
+                        # If something bad happens, we just want to preview anyway...
+            # else fall through in a preview
+            req.args['preview'] = True
 
             # Preview an existing ticket (after a Preview or a failed Save)
             data.update({

