diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+debug-me (1.20190926) unstable; urgency=medium
+
+  * Avoid a crash when run without a controlling tty, which may happen
+    in some container environments.
+  * Update to lts-13.29, support ghc 8.6.5, and aeson 1.4.
+
+ -- Joey Hess <id@joeyh.name>  Thu, 26 Sep 2019 20:05:24 -0400
+
 debug-me (1.20181208) unstable; urgency=medium
 
   * Update to lts-12.10, support ghc 8.4, and aeson 1.3.
diff --git a/ControlWindow.hs b/ControlWindow.hs
--- a/ControlWindow.hs
+++ b/ControlWindow.hs
@@ -98,9 +98,20 @@
 type PromptChan = TChan Prompt
 type ResponseChan = TChan Response
 
+-- | Get a name for the debug-me user. When possible this will be the
+-- actual username, but failing that, anything reasonable will do,
+-- since it's only ever displayed to the person they are communicating
+-- with.
+getUserName :: IO String
+getUserName = do
+	loginname <- try getLoginName :: IO (Either SomeException String)
+	case loginname of
+		Right n -> return n
+		Left _ -> return "user"
+
 collectOutput :: TMChan ControlOutput -> PromptChan -> ResponseChan -> IO ()
 collectOutput ochan promptchan responsechan = do
-	myusername <- fromString <$> getLoginName
+	myusername <- fromString <$> getUserName
 	loop myusername
   where
 	loop myusername = do
diff --git a/Role/User.hs b/Role/User.hs
--- a/Role/User.hs
+++ b/Role/User.hs
@@ -247,17 +247,17 @@
 getDeveloperMessage' :: MissingHashes (Message Entered) -> TMChan (Message Seen) -> TVar UserState -> POSIXTime -> STM Input
 getDeveloperMessage' (MissingHashes wiremsg) ochan us now = do
 	st <- readTVar us
-	Developer msg <- restoreHashes (userStateRecentActivity us) (MissingHashes (Developer wiremsg))
+	msg <- restoreHashes (userStateRecentActivity us) (MissingHashes (Developer wiremsg))
 	case msg of
-		ControlMessage (Control (SessionKey spk _) _) -> do
+		Developer cmsg@(ControlMessage (Control (SessionKey spk _) _)) -> do
 			let sigverifier = mkSigVerifier $ case spk of
 				GpgSigned pk _ _ -> pk
 				UnSigned pk -> pk
-			if verifySigned sigverifier msg
-				then return (InputMessage msg)
-				else return (BadlySignedMessage msg)
-		_ -> if verifySigned (sigVerifier st) msg
-			then case msg of
+			if verifySigned sigverifier cmsg
+				then return (InputMessage cmsg)
+				else return (BadlySignedMessage cmsg)
+		Developer cmsg -> if verifySigned (sigVerifier st) cmsg
+			then case cmsg of
 				ActivityMessage entered -> do
 					-- Don't need to retain backlog
 					-- before the Activity that entered
@@ -266,22 +266,26 @@
 						truncateBacklog (backLog st) entered
 					if isLegalEntered entered (st { backLog = bl' })
 						then do
-							let l = mkLog (Developer msg) now
+							let l = mkLog (Developer cmsg) now
 							writeTVar us $ st 
 								{ backLog = l :| toList bl'
 								, lastAcceptedEntered = Just (hash entered)
 								}
-							return (InputMessage msg)
+							return (InputMessage cmsg)
 						else do
 							let reject = EnteredRejected 
 								{ enteredRejected = hash entered
 								, enteredLastAccepted = lastAcceptedEntered st
 								}
-							RejectedMessage msg
+							RejectedMessage cmsg
 								<$> sendDeveloper ochan us reject now
 				ControlMessage (Control _ _) ->
-					return (InputMessage msg)
-			else return (BadlySignedMessage msg)
+					return (InputMessage cmsg)
+			else return (BadlySignedMessage cmsg)
+		-- This cannot really happen, because restoreHashes is
+		-- always passed a Developer message, but ghc doesn't know
+		-- that.
+		User _ -> error "unexpectedly received User message where Developer message expected"
 
 -- | Truncate the Backlog to remove entries older than the one
 -- that the Activity Entered refers to, but only if the referred
diff --git a/debug-me.cabal b/debug-me.cabal
--- a/debug-me.cabal
+++ b/debug-me.cabal
@@ -1,5 +1,5 @@
 Name: debug-me
-Version: 1.20181208
+Version: 1.20190926
 Cabal-Version: >= 1.8
 Maintainer: Joey Hess <joey@kitenet.net>
 Author: Joey Hess
@@ -63,7 +63,7 @@
     , stm-chans (>= 3.0)
     , posix-pty (>= 0.2.1)
     , terminal-size (>= 0.3)
-    , aeson (>= 0.11 && < 1.4)
+    , aeson (>= 0.11 && < 1.5)
     , sandi (>= 0.4)
     , text (>= 1.2.2)
     , optparse-applicative (>= 0.12)
