diff --git a/src/engine/execute.js b/src/engine/execute.js
index 9c53d66c3..be35e31b5 100644
--- a/src/engine/execute.js
+++ b/src/engine/execute.js
@@ -102,7 +102,7 @@ const handleReport = function (resolvedValue, sequencer, thread, blockCached) {
     }
 };
 
-const handlePromise = (primitiveReportedValue, sequencer, thread, blockCached) => {
+const handlePromise = (primitiveReportedValue, sequencer, thread, blockCached, lastOperation) => {
     if (thread.status === Thread.STATUS_RUNNING) {
         // Primitive returned a promise; automatically yield thread.
         thread.status = Thread.STATUS_PROMISE_WAIT;
@@ -110,7 +110,8 @@ const handlePromise = (primitiveReportedValue, sequencer, thread, blockCached) =
     // Promise handlers
     primitiveReportedValue.then(resolvedValue => {
         handleReport(resolvedValue, sequencer, thread, blockCached);
-        if (typeof resolvedValue === 'undefined') {
+        // If its a command block.
+        if (lastOperation && typeof resolvedValue === 'undefined') {
             let stackFrame;
             let nextBlockId;
             do {
@@ -131,8 +132,6 @@ const handlePromise = (primitiveReportedValue, sequencer, thread, blockCached) =
             } while (stackFrame !== null && !stackFrame.isLoop);
 
             thread.pushStack(nextBlockId);
-        } else {
-            thread.popStack();
         }
     }, rejectionReason => {
         // Promise rejected: the primitive had some error.
@@ -407,7 +406,44 @@ const execute = function (sequencer, thread) {
         const reported = currentStackFrame.reported;
         // Reinstate all the previous values.
         for (; i < reported.length; i++) {
-            const {opCached, inputValue} = reported[i];
+            const {opCached: oldOpCached, inputValue} = reported[i];
+
+            const opCached = ops.find(op => op.id === oldOpCached);
+
+            if (opCached) {
+                const inputName = opCached._parentKey;
+                const argValues = opCached._parentValues;
+
+                if (inputName === 'BROADCAST_INPUT') {
+                    // Something is plugged into the broadcast input.
+                    // Cast it to a string. We don't need an id here.
+                    argValues.BROADCAST_OPTION.id = null;
+                    argValues.BROADCAST_OPTION.name = cast.toString(inputValue);
+                } else {
+                    argValues[inputName] = inputValue;
+                }
+            }
+        }
+
+        // Find the last reported block that is still in the set of operations.
+        // This way if the last operation was removed, we'll find the next
+        // candidate. If an earlier block that was performed was removed then
+        // we'll find the index where the last operation is now.
+        if (reported.length > 0) {
+            const lastExisting = reported.reverse().find(report => ops.find(op => op.id === report.opCached));
+            if (lastExisting) {
+                i = ops.findIndex(opCached => opCached.id === lastExisting.opCached) + 1;
+            } else {
+                i = 0;
+            }
+        }
+
+        // The reporting block must exist and must be the next one in the sequence of operations.
+        if (thread.justReported !== null && ops[i] && ops[i].id === currentStackFrame.reporting) {
+            const opCached = ops[i];
+            const inputValue = thread.justReported;
+
+            thread.justReported = null;
 
             const inputName = opCached._parentKey;
             const argValues = opCached._parentValues;
@@ -420,17 +456,11 @@ const execute = function (sequencer, thread) {
             } else {
                 argValues[inputName] = inputValue;
             }
+
+            i += 1;
         }
 
-        // Find the last reported block that is still in the set of operations.
-        // This way if the last operation was removed, we'll find the next
-        // candidate. If an earlier block that was performed was removed then
-        // we'll find the index where the last operation is now.
-        if (reported.length > 0) {
-            const lastExisting = reported.reverse().find(report => ops.find(op => op.id === report[0].id));
-            i = ops.findIndex(opCached => opCached.id === lastExisting.id) + 1;
-        }
-
+        currentStackFrame.reporting = null;
         currentStackFrame.reported = null;
     }
 
@@ -471,23 +501,33 @@ const execute = function (sequencer, thread) {
 
         // If it's a promise, wait until promise resolves.
         if (isPromise(primitiveReportedValue)) {
-            handlePromise(primitiveReportedValue, sequencer, thread, opCached);
+            handlePromise(primitiveReportedValue, sequencer, thread, opCached, last);
 
+            // Store the already reported values. They will be thawed into the
+            // future versions of the same operations by block id. The reporting
+            // operation if it is promise waiting will set its parent value at
+            // that time.
+            thread.justReported = null;
+            currentStackFrame.reporting = ops[i].id;
             currentStackFrame.reported = ops.slice(0, i).map(reportedCached => {
                 const inputName = reportedCached._parentKey;
                 const reportedValues = reportedCached._parentValues;
 
                 if (inputName === 'BROADCAST_INPUT') {
                     return {
-                        opCached: reportedCached,
+                        opCached: reportedCached.id,
                         inputValue: reportedValues[inputName].BROADCAST_OPTION.name
                     };
                 }
                 return {
-                    opCached: reportedCached,
+                    opCached: reportedCached.id,
                     inputValue: reportedValues[inputName]
                 };
             });
+
+            // We are waiting for a promise. Stop running this set of operations
+            // and continue them later after thawing the reported values.
+            break;
         } else if (thread.status === Thread.STATUS_RUNNING) {
             if (last) {
                 if (typeof primitiveReportedValue === 'undefined') {
diff --git a/src/engine/thread.js b/src/engine/thread.js
index 9c07f6637..316642222 100644
--- a/src/engine/thread.js
+++ b/src/engine/thread.js
@@ -32,6 +32,12 @@ class _StackFrame {
          */
         this.justReported = null;
 
+        /**
+         * The active block that is waiting on a promise.
+         * @type {string}
+         */
+        this.reporting = '';
+
         /**
          * Persists reported inputs during async block.
          * @type {Object}