diff --git a/src/lib/blocks.js b/src/lib/blocks.js
index 39a8c70e6209d3682f615f3804c1a2bdfd7426ca..bbaf7a61157e7ad1322e7ea760def67b84bbe92c 100644
--- a/src/lib/blocks.js
+++ b/src/lib/blocks.js
@@ -67,7 +67,11 @@ export default function (vm) {
 
     const cloneMenu = function () {
         if (vm.editingTarget && vm.editingTarget.isStage) {
-            return spriteMenu();
+            const menu = spriteMenu();
+            if (menu.length === 0) {
+                return [['', '']]; // Empty menu matches Scratch 2 behavior
+            }
+            return menu;
         }
         return [['myself', '_myself_']].concat(spriteMenu());
     };
diff --git a/test/integration/test.js b/test/integration/test.js
index 57feb8e085effb080c5bd20731116e2ae7d46b37..eaf11ead1fc769ba407cb07c373db13865946d2b 100644
--- a/test/integration/test.js
+++ b/test/integration/test.js
@@ -163,4 +163,18 @@ describe('costumes, sounds and variables', () => {
         const logs = await getLogs(errorWhitelist);
         await expect(logs).toEqual([]);
     });
+
+    test('Deleting only sprite does not crash', async () => {
+        const spriteTileContext = '*[starts-with(@class,"react-contextmenu-wrapper")]';
+        await loadUri(uri);
+        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
+        await rightClickText('Sprite1', spriteTileContext);
+        await clickText('delete', spriteTileContext);
+        await driver.switchTo().alert()
+            .accept();
+        // Confirm that the stage has been switched to
+        await findByText('Stage selected: no motion blocks');
+        const logs = await getLogs(errorWhitelist);
+        await expect(logs).toEqual([]);
+    });
 });