diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index 3c9473b89ce1f68b324540c46790106420d951d6..a70e0a6323334ce95ab230a97f96df7e4552c979 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -202,7 +202,10 @@ void glist_delete(t_glist *x, t_gobj *y)
         if (drawcommand)
         {
             tmpl = template_findbydrawcommand(y);
-            canvas_redrawallfortemplate(tmpl, 2);
+            if (!(canvas_isgroup(canvas) && canvas->gl_isdeleting))
+            {
+                canvas_redrawallfortemplate(tmpl, 2);
+            }
         }
         if (glist_isvisible(canvas))
             gobj_vis(y, x, 0);
@@ -234,7 +237,10 @@ void glist_delete(t_glist *x, t_gobj *y)
         pd_free(&y->g_pd);
         if (chkdsp) canvas_update_dsp();
         if (drawcommand)
-            canvas_redrawallfortemplate(tmpl, 1);
+        {
+            if (!(canvas_isgroup(canvas) && canvas->gl_isdeleting))
+                canvas_redrawallfortemplate(tmpl, 1);
+        }
         canvas_setdeleting(canvas, wasdeleting);
         x->gl_valid = ++glist_valid;
         if (late_rtext_free)
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index bfa611d3a04b485df7f705e10a22c70428c2eb5a..3c75a8a5c99794560df7e7c10e325ca7771a5029 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -137,24 +137,65 @@ int template_hasxy(t_template *template)
         return 0;
 }
 
-int template_cancreate(t_template *template)
+int template_check_array_fields(t_symbol *structname, t_template *template)
 {
+    /* We're calling this from template_cancreate as well as
+       gtemplate_cancreate.
+       With gtemplate_cancreate, the t_template doesn't exist yet.
+       So we send the struct name to see if it matches the name of any
+       array field templates that our gtemplate will depend on. If we find
+       a match we will refuse to create the gtemplate.
+       However, template_cancreate starts from the struct name for a template
+       that already exists.  So on the first time through this recursive
+       function, there isn't a containing structname yet.
+       So we suppress this conditional the first
+       time through the recursive loop, and then set the structname for
+       all subsequent iterations through the loop. */
+    if (structname && structname == template->t_sym)
+    {
+        return 0;
+    }
     int i, nitems = template->t_n;
     t_dataslot *datatypes = template->t_vec;
     t_template *elemtemplate;
     for (i = 0; i < nitems; i++, datatypes++)
-        if (datatypes->ds_type == DT_ARRAY &&
-            (!(elemtemplate = template_findbyname(datatypes->ds_arraytemplate))
-                || !template_cancreate(elemtemplate)))
     {
-        t_object *ob = template_getstruct(template);
-        pd_error(ob, "%s: no such template",
-            datatypes->ds_arraytemplate->s_name);
-        return (0);
+        if (datatypes->ds_type == DT_ARRAY)
+        {
+            elemtemplate = template_findbyname(datatypes->ds_arraytemplate);
+            if (!(elemtemplate))
+            {
+                t_object *ob = template_getstruct(template);
+                pd_error(ob, "%s: no such template",
+                    datatypes->ds_arraytemplate->s_name);
+                return (0);
+            }
+            else if (elemtemplate->t_sym == structname)
+            {
+                t_object *ob = template_getstruct(template);
+                pd_error(ob, "%s: circular dependency",
+                    datatypes->ds_arraytemplate->s_name);
+                return (0);
+            }
+            else
+            {
+                if (!structname)
+                {
+                    structname = template->t_sym;
+                }
+                return (template_check_array_fields(structname, elemtemplate));
+            }
+        }
     }
     return (1);
 }
 
+int template_cancreate(t_template *template)
+{
+    /* we send "0" for the structname since there is no container struct */
+    return (template_check_array_fields(0, template));
+}
+
     /* make a new scalar and add to the glist.  We create a "gp" here which
     will be used for array items to point back here.  This gp doesn't do
     reference counting or "validation" updates though; the parent won't go away
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index b3aa5f0213cb1dc2394c266f77b0725684d5181f..1b053d817c130538fe19f997aacb7ace3b9ee043 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -580,6 +580,8 @@ instructions for the template.  The template doesn't go away when the
 "struct" is deleted, so that you can replace it with
 another one to add new fields, for example. */
 
+static void gtemplate_free(t_gtemplate *x);
+
 static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv)
 {
     t_canvas *cur = canvas_getcurrent();
@@ -626,16 +628,6 @@ static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv)
                 our own and conform it. */
             t_template *y = template_new(&s_, argc, argv);
 
-            /* I'm not _exactly_ sure about this. It's possible
-               that the user could screw up a nested array construction
-               and end up with scalars that aren't able to conform. On
-               the other hand, this keeps us from crashing if a non-
-               existent array template is typed into the box. */
-            if (!template_cancreate(y))
-            {
-                return 0;
-            }
-
             canvas_redrawallfortemplate(t, 2);
                 /* Unless the new template is different from the old one,
                 there's nothing to do.  */
@@ -656,17 +648,66 @@ static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv)
             /* otherwise make a new one and we're the only struct on it. */
         x->x_template = t = template_new(sym, argc, argv);
         t->t_list = x;
-    }
+   }
     outlet_new(&x->x_obj, 0);
     return (x);
 }
 
+int template_check_array_fields(t_symbol *structname, t_template *template);
+
+/* probably duplicating some code from template_new here... */
+int gtemplate_cancreate(t_symbol *templatename, int argc, t_atom *argv)
+{
+    while (argc > 1)
+    {
+        t_symbol *typesym = argv[0].a_w.w_symbol;
+        if (typesym == &s_float || typesym == &s_symbol)
+        {
+            argc -= 2;
+            argv += 2; 
+        }
+        else if (typesym == gensym("array"))
+        {
+            if (argc > 2 && argv[2].a_type == A_SYMBOL)
+            {
+                /* check for cancreation here */
+                t_template *elemtemplate =
+                    template_findbyname(canvas_makebindsym(argv[2].a_w.w_symbol));
+                if (!elemtemplate ||
+                    !template_check_array_fields(
+                        canvas_makebindsym(templatename), elemtemplate))
+                {
+                    return 0;
+                }
+                argc -= 3;
+                argv += 3;
+            }
+            else
+            {
+                argc -= 2;
+                argv += 2;
+            }
+        }
+        else
+        {
+            argc -= 2;
+            argv += 2;
+        }
+    }
+    return 1;
+}
+
 static void *gtemplate_new(t_symbol *s, int argc, t_atom *argv)
 {
     t_symbol *sym = atom_getsymbolarg(0, argc, argv);
     if (argc >= 1)
         argc--; argv++;
-    return (gtemplate_donew(canvas_makebindsym(sym), argc, argv));
+    if (gtemplate_cancreate(sym, argc, argv))
+    {
+        return (gtemplate_donew(canvas_makebindsym(sym), argc, argv));
+    }
+    else
+        return 0;
 }
 
     /* old version (0.34) -- delete 2003 or so */