diff --git a/pd/nw/index.js b/pd/nw/index.js
index 09249b5a56b1724c682764cf18772118926fa055..0bb59eb34871d96bbf8ded52b04cb7cfaaa1a4b3 100644
--- a/pd/nw/index.js
+++ b/pd/nw/index.js
@@ -301,14 +301,27 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
             pdgui.set_dialogwin(cid, new_win);
         }
         new_win.on("loaded", function() {
-            new_win.eval(null, eval_string);
+            // We need to check here if we're still the window pointed to
+            // by the GUI's array of toplevel windows. It can easily happen
+            // that we're not-- for example the user could send a stream
+            // of [vis 1, vis 0, vis 1, etc.( to a single subpatch. In that
+            // case the asynchronous Pd <-> GUI communication might
+            // momentarily create multiple windows of that same subpatch.
+            // Here we just let them load, then close any that don't match
+            // the cid we added above.
+            // Additionally, we check to make sure that the cid is registered
+            // as a loaded canvas. If not, we assume it got closed before
+            // we were able to finish loading the browser window (e.g.,
+            // with a [vis 1, vis 0( message). In that case we kill the window.
+            if (new_win === pdgui.get_patchwin(cid) &&
+                pdgui.window_is_loaded(cid)) {
+                // initialize the window
+                new_win.eval(null, eval_string);
+            } else {
+                new_win.close(true);
+            }
         });
     });
-    //pdgui.post("attr_array is " + attr_array);
-    //pdgui.post("eval string is " + eval_string);
-    //if (attr_array !== null) {
-    //    pdgui.post("attr_array is " + attr_array.toString());
-    //}
 }
 
 // Pd Window Menu Bar
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 4bc777dddaadff18c8771b0df031f63f52204e6b..03675f8fcf1b700a532136a7c52d2315b8411877 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -512,9 +512,15 @@ exports.menu_new = menu_new;
 
 // requires nw.js API
 function gui_window_close(cid) {
-    nw_close_window(patchwin[cid]);
+    // for some edge cases like [vis 1, vis 0(--[send subpatch] we
+    // may not have finished creating the window yet. So we check to
+    // make sure the canvas cid exists...
+    if (patchwin[cid]) {
+        nw_close_window(patchwin[cid]);
+    }
     // remove reference to the window from patchwin object
     patchwin[cid] = null;
+    loaded[cid] = null;
 }
 
 function menu_k12_open_demos () {
@@ -988,6 +994,12 @@ function gui_canvas_set_title(cid, name, args, dir, dirty_flag) {
     patchwin[cid].title = title;
 }
 
+function window_is_loaded(cid) {
+    return (loaded[cid] === 1);
+}
+
+exports.window_is_loaded = window_is_loaded;
+
 // create a new canvas
 function gui_canvas_new(cid, width, height, geometry, editmode, name, dir, dirty_flag, cargs) {
     // hack for buggy tcl popups... should go away for node-webkit
@@ -3543,7 +3555,11 @@ function gui_cord_inspector_flash(cid, state) {
 // Window functions
 
 function gui_raise_window(cid) {
-    patchwin[cid].focus();
+    // Check if the window exists, for edge cases like
+    // [vis 1, vis1(---[send this_canvas]
+    if (patchwin[cid]) {
+        patchwin[cid].focus();
+    }
 }
 
 // Unfortunately DOM window.focus doesn't actually focus the window, so we