diff --git a/client-msg.c b/client-msg.c
index 7d7166ca..5a95ff62 100644
--- a/client-msg.c
+++ b/client-msg.c
@@ -25,16 +25,16 @@
 
 #include "tmux.h"
 
-int	client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
-int	client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
-int	client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
-int	client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
-int	client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
-int	client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
+int	client_msg_fn_detach(struct hdr *, struct client_ctx *);
+int	client_msg_fn_error(struct hdr *, struct client_ctx *);
+int	client_msg_fn_shutdown(struct hdr *, struct client_ctx *);
+int	client_msg_fn_exit(struct hdr *, struct client_ctx *);
+int	client_msg_fn_exited(struct hdr *, struct client_ctx *);
+int	client_msg_fn_suspend(struct hdr *, struct client_ctx *);
 
 struct client_msg {
 	enum hdrtype   type;
-	int	       (*fn)(struct hdr *, struct client_ctx *, char **);
+	int	       (*fn)(struct hdr *, struct client_ctx *);
 };
 struct client_msg client_msg_table[] = {
 	{ MSG_DETACH, client_msg_fn_detach },
@@ -46,7 +46,7 @@ struct client_msg client_msg_table[] = {
 };
 
 int
-client_msg_dispatch(struct client_ctx *cctx, char **error)
+client_msg_dispatch(struct client_ctx *cctx)
 {
 	struct hdr		 hdr;
 	struct client_msg	*msg;
@@ -61,70 +61,67 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
 
 	for (i = 0; i < nitems(client_msg_table); i++) {
 		msg = client_msg_table + i;
-		if (msg->type == hdr.type) {
-			if (msg->fn(&hdr, cctx, error) != 0)
-				return (-1);
-			return (0);
-		}
+		if (msg->type == hdr.type)
+			return (msg->fn(&hdr, cctx));
 	}
 	fatalx("unexpected message");
 }
 
 int
-client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
+client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx)
 {
+	char	*errstr;
+
 	if (hdr->size == SIZE_MAX)
 		fatalx("bad MSG_ERROR size");
 
-	*error = xmalloc(hdr->size + 1);
-	buffer_read(cctx->srv_in, *error, hdr->size);
-	(*error)[hdr->size] = '\0';
+	errstr = xmalloc(hdr->size + 1);
+	buffer_read(cctx->srv_in, errstr, hdr->size);
+	errstr[hdr->size] = '\0';
 
+	cctx->errstr = errstr;
 	return (-1);
 }
 
 int
-client_msg_fn_detach(
-    struct hdr *hdr, struct client_ctx *cctx, unused char **error)
+client_msg_fn_detach(struct hdr *hdr, struct client_ctx *cctx)
 {
 	if (hdr->size != 0)
 		fatalx("bad MSG_DETACH size");
 
 	client_write_server(cctx, MSG_EXITING, NULL, 0);
-	cctx->flags |= CCTX_DETACH;
+	cctx->exittype = CCTX_DETACH;
 
 	return (0);
 }
 
 int
 client_msg_fn_shutdown(
-    struct hdr *hdr, struct client_ctx *cctx, unused char **error)
+    struct hdr *hdr, struct client_ctx *cctx)
 {
 	if (hdr->size != 0)
 		fatalx("bad MSG_SHUTDOWN size");
 
 	client_write_server(cctx, MSG_EXITING, NULL, 0);
-	cctx->flags |= CCTX_SHUTDOWN;
+	cctx->exittype = CCTX_SHUTDOWN;
 
 	return (0);
 }
 
 int
-client_msg_fn_exit(
-    struct hdr *hdr, struct client_ctx *cctx, unused char **error)
+client_msg_fn_exit(struct hdr *hdr, struct client_ctx *cctx)
 {
 	if (hdr->size != 0)
 		fatalx("bad MSG_EXIT size");
 
 	client_write_server(cctx, MSG_EXITING, NULL, 0);
-	cctx->flags |= CCTX_EXIT;
+	cctx->exittype = CCTX_EXIT;
 
 	return (0);
 }
 
 int
-client_msg_fn_exited(
-    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
+client_msg_fn_exited(struct hdr *hdr, unused struct client_ctx *cctx)
 {
 	if (hdr->size != 0)
 		fatalx("bad MSG_EXITED size");
@@ -133,8 +130,7 @@ client_msg_fn_exited(
 }
 
 int
-client_msg_fn_suspend(
-    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
+client_msg_fn_suspend(struct hdr *hdr, unused struct client_ctx *cctx)
 {
 	struct sigaction	 act;
 
diff --git a/client.c b/client.c
index 5ad15321..9bd731a8 100644
--- a/client.c
+++ b/client.c
@@ -155,7 +155,7 @@ client_main(struct client_ctx *cctx)
 			sigcont = 0;
 		}
 
-		switch (client_msg_dispatch(cctx, &error)) {
+		switch (client_msg_dispatch(cctx)) {
 		case -1:
 			goto out;
 		case 0:
@@ -179,8 +179,10 @@ client_main(struct client_ctx *cctx)
 			fatal("poll failed");
 		}
 
-		if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
-			goto server_dead;
+		if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0) {
+			cctx->exittype = CCTX_DIED;
+			break;
+		}
 	}
 
 out:
@@ -188,28 +190,23 @@ out:
  		printf("[terminated]\n");
  		return (1);
  	}
-
-	if (cctx->flags & CCTX_SHUTDOWN) {
+	switch (cctx->exittype) {
+	case CCTX_DIED:
+		printf("[lost server]\n");
+		return (0);
+	case CCTX_SHUTDOWN:
 		printf("[server exited]\n");
 		return (0);
-	}
-
-	if (cctx->flags & CCTX_EXIT) {
+	case CCTX_EXIT:
 		printf("[exited]\n");
 		return (0);
-	}
-
-	if (cctx->flags & CCTX_DETACH) {
+	case CCTX_DETACH:
 		printf("[detached]\n");
 		return (0);
+	default:
+		printf("[error: %s]\n", cctx->errstr);
+		return (1);
 	}
-
-	printf("[error: %s]\n", error);
-	return (1);
-
-server_dead:
-	printf("[lost server]\n");
-	return (0);
 }
 
 void
diff --git a/tmux.h b/tmux.h
index 455bb2ac..e57b607c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -845,10 +845,13 @@ struct client_ctx {
 	struct buffer	*srv_in;
 	struct buffer	*srv_out;
 
-#define CCTX_DETACH 0x1
-#define CCTX_EXIT 0x2
-#define CCTX_SHUTDOWN 0x4
-	int 		 flags;
+	enum {
+		CCTX_DETACH,
+		CCTX_EXIT,
+		CCTX_DIED,
+		CCTX_SHUTDOWN,
+	} exittype;
+	const char	*errstr;
 };
 
 /* Key/command line command. */
@@ -1261,7 +1264,7 @@ int	 client_init(char *, struct client_ctx *, int, int);
 int	 client_main(struct client_ctx *);
 
 /* client-msg.c */
-int	 client_msg_dispatch(struct client_ctx *, char **);
+int	 client_msg_dispatch(struct client_ctx *);
 
 /* client-fn.c */
 void	 client_write_server(struct client_ctx *, enum hdrtype, void *, size_t);