diff --git a/core/block_svg.js b/core/block_svg.js
index b12d5d90..6bb838e9 100644
--- a/core/block_svg.js
+++ b/core/block_svg.js
@@ -690,6 +690,10 @@ Blockly.BlockSvg.prototype.duplicateAndDragCallback_ = function() {
       // Using domToBlock instead of domToWorkspace means that the new block
       // will be placed at position (0, 0) in main workspace units.
       var newBlock = Blockly.Xml.domToBlock(xml, ws);
+
+      // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste
+      Blockly.utils.changeObscuredShadowIds(newBlock);
+
       var svgRootNew = newBlock.getSvgRoot();
       if (!svgRootNew) {
         throw new Error('newBlock is not rendered.');
diff --git a/core/utils.js b/core/utils.js
index 9b088977..4669ea2c 100644
--- a/core/utils.js
+++ b/core/utils.js
@@ -931,3 +931,26 @@ Blockly.utils.setCssTransform = function(node, transform) {
   node.style['transform'] = transform;
   node.style['-webkit-transform'] = transform;
 };
+
+
+/**
+ * Re-assign obscured shadow blocks new IDs to prevent collisions
+ * Scratch specific to help the VM handle deleting obscured shadows.
+ * @param {Blockly.Block} block the root block to be processed.
+ */
+Blockly.utils.changeObscuredShadowIds = function(block) {
+  var blocks = block.getDescendants();
+  for (var i = blocks.length - 1; i >= 0; i--) {
+    var descendant = blocks[i];
+    for (var j = 0; j < descendant.inputList.length; j++) {
+      var connection = descendant.inputList[j].connection;
+      if (connection) {
+        var shadowDom = connection.getShadowDom();
+        if (shadowDom) {
+          shadowDom.setAttribute('id', Blockly.utils.genUid());
+          connection.setShadowDom(shadowDom);
+        }
+      }
+    }
+  }
+};
diff --git a/core/workspace_svg.js b/core/workspace_svg.js
index 69d58eba..985dcf78 100644
--- a/core/workspace_svg.js
+++ b/core/workspace_svg.js
@@ -945,22 +945,12 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) {
   try {
     var block = Blockly.Xml.domToBlock(xmlBlock, this);
 
+    // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste
+    Blockly.utils.changeObscuredShadowIds(block);
+
     var blocks = block.getDescendants();
     for (var i = blocks.length - 1; i >= 0; i--) {
       var descendant = blocks[i];
-
-      // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste
-      for (var j = 0; j < descendant.inputList.length; j++) {
-        var connection = descendant.inputList[j].connection;
-        if (connection) {
-          var shadowDom = connection.getShadowDom();
-          if (shadowDom) {
-            shadowDom.setAttribute('id', Blockly.utils.genUid());
-            connection.setShadowDom(shadowDom);
-          }
-        }
-      }
-
       // Rerender to get around problem with IE and Edge not measuring text
       // correctly when it is hidden.
       if (goog.userAgent.IE || goog.userAgent.EDGE) {