Index: src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java	(revision 14828)
+++ src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java	(working copy)
@@ -34,6 +34,7 @@
 import org.openstreetmap.josm.actions.ValidateAction;
 import org.openstreetmap.josm.actions.relation.EditRelationAction;
 import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.UndoRedoHandler;
 import org.openstreetmap.josm.data.osm.DataSelectionListener;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -601,11 +602,10 @@
             // do nothing
         }
 
-        protected void fixError(TestError error) throws InterruptedException, InvocationTargetException {
+        protected void fixError(TestError error) {
             if (error.isFixable()) {
                 final Command fixCommand = error.getFix();
                 if (fixCommand != null) {
-                    SwingUtilities.invokeAndWait(() -> UndoRedoHandler.getInstance().addNoRedraw(fixCommand));
                     fixCommands.add(fixCommand);
                 }
                 // It is wanted to ignore an error if it said fixable, even if fixCommand was null
@@ -622,25 +622,27 @@
                 monitor.setTicksCount(testErrors.size());
                 final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
                 int i = 0;
-                SwingUtilities.invokeAndWait(ds::beginUpdate);
-                try {
-                    for (TestError error: testErrors) {
-                        i++;
-                        monitor.subTask(tr("Fixing ({0}/{1}): ''{2}''", i, testErrors.size(), error.getMessage()));
-                        if (this.canceled)
-                            return;
-                        fixError(error);
-                        monitor.worked(1);
-                    }
-                } finally {
-                    SwingUtilities.invokeAndWait(ds::endUpdate);
+                for (TestError error: testErrors) {
+                    i++;
+                    monitor.subTask(tr("Fixing ({0}/{1}): ''{2}''", i, testErrors.size(), error.getMessage()));
+                    if (this.canceled)
+                        return;
+                    fixError(error);
+                    monitor.worked(1);
                 }
                 monitor.subTask(tr("Updating map ..."));
+                List<TestError> oldErrors = new ArrayList<>(tree.getErrors());
+                tree.getErrors().clear();
                 SwingUtilities.invokeAndWait(() -> {
-                    UndoRedoHandler.getInstance().afterAdd(fixCommands);
-                    invalidateValidatorLayers();
-                    tree.resetErrors();
+                    ds.beginUpdate();
+                    UndoRedoHandler.getInstance().add(new SequenceCommand(tr("fixed by Validator"), fixCommands, true));
+                    ds.endUpdate();
                 });
+                invalidateValidatorLayers();
+
+                oldErrors.removeIf(error -> error.getPrimitives().stream().anyMatch(OsmPrimitive::isDeleted));
+                tree.getErrors().addAll(oldErrors);
+                tree.resetErrors();
             } catch (InterruptedException | InvocationTargetException e) {
                 // FIXME: signature of realRun should have a generic checked exception we could throw here
                 throw new JosmRuntimeException(e);
Index: src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(revision 14828)
+++ src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(working copy)
@@ -483,9 +483,8 @@
 
     @Override public void primitivesRemoved(PrimitivesRemovedEvent event) {
         // Remove purged primitives (fix #8639)
-        if (errors != null) {
-            final Set<? extends OsmPrimitive> deletedPrimitives = new HashSet<>(event.getPrimitives());
-            errors.removeIf(error -> error.getPrimitives().stream().anyMatch(deletedPrimitives::contains));
+        if (errors != null && !errors.isEmpty()) {
+            errors.removeIf(error -> error.getPrimitives().stream().anyMatch(OsmPrimitive::isDeleted));
         }
     }
 
