patch 7.4.1827
Problem:    No error when invoking a callback when it's not safe.
Solution:   Add an error message.  Avoid the error when freeing a channel.
diff --git a/src/channel.c b/src/channel.c
index 159a3a0..a7f4c4b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -59,6 +59,9 @@
 /* Whether a redraw is needed for appending a line to a buffer. */
 static int channel_need_redraw = FALSE;
 
+/* Whether we are inside channel_parse_messages() or another situation where it
+ * is safe to invoke callbacks. */
+static int safe_to_invoke_callback = 0;
 
 #ifdef WIN32
     static int
@@ -403,8 +406,15 @@
 {
     if (!in_free_unref_items)
     {
-	channel_free_contents(channel);
-	channel_free_channel(channel);
+	if (safe_to_invoke_callback == 0)
+	{
+	    channel->ch_to_be_freed = TRUE;
+	}
+	else
+	{
+	    channel_free_contents(channel);
+	    channel_free_channel(channel);
+	}
     }
 }
 
@@ -444,6 +454,10 @@
     int		did_free = FALSE;
     channel_T	*ch;
 
+    /* This is invoked from the garbage collector, which only runs at a safe
+     * point. */
+    ++safe_to_invoke_callback;
+
     for (ch = first_channel; ch != NULL; ch = ch->ch_next)
 	if (!channel_still_useful(ch)
 				 && (ch->ch_copyID & mask) != (copyID & mask))
@@ -453,6 +467,8 @@
 	    channel_free_contents(ch);
 	    did_free = TRUE;
 	}
+
+    --safe_to_invoke_callback;
     return did_free;
 }
 
@@ -1450,6 +1466,9 @@
     typval_T	rettv;
     int		dummy;
 
+    if (safe_to_invoke_callback == 0)
+	EMSG("INTERNAL: Invoking callback when it is not safe");
+
     argv[0].v_type = VAR_CHANNEL;
     argv[0].vval.v_channel = channel;
 
@@ -3515,6 +3534,8 @@
     int		r;
     int		part = PART_SOCK;
 
+    ++safe_to_invoke_callback;
+
     /* Only do this message when another message was given, otherwise we get
      * lots of them. */
     if (did_log_msg)
@@ -3532,6 +3553,13 @@
 	    channel = first_channel;
 	    continue;
 	}
+	if (channel->ch_to_be_freed)
+	{
+	    channel_free(channel);
+	    /* channel has been freed, start over */
+	    channel = first_channel;
+	    continue;
+	}
 	if (channel->ch_refcount == 0 && !channel_still_useful(channel))
 	{
 	    /* channel is no longer useful, free it */
@@ -3572,6 +3600,8 @@
 	redraw_after_callback();
     }
 
+    --safe_to_invoke_callback;
+
     return ret;
 }
 
diff --git a/src/structs.h b/src/structs.h
index a2b38bf..24d819b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1419,6 +1419,8 @@
     int		ch_to_be_closed; /* When TRUE reading or writing failed and
 				  * the channel must be closed when it's safe
 				  * to invoke callbacks. */
+    int		ch_to_be_freed; /* When TRUE channel must be freed when it's
+				 * safe to invoke callbacks. */
     int		ch_error;	/* When TRUE an error was reported.  Avoids
 				 * giving pages full of error messages when
 				 * the other side has exited, only mention the
diff --git a/src/version.c b/src/version.c
index 373aff2..266e591 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1827,
+/**/
     1826,
 /**/
     1825,