diff --git a/creatur.cabal b/creatur.cabal
--- a/creatur.cabal
+++ b/creatur.cabal
@@ -1,5 +1,5 @@
 Name:              creatur
-Version:           5.8.2
+Version:           5.9.0
 Stability:         experimental
 Synopsis:          Framework for artificial life experiments.
 Description:       A software framework for automating experiments
@@ -36,7 +36,7 @@
 source-repository this
   type:     git
   location: https://github.com/mhwombat/creatur.git
-  tag:      5.8.2
+  tag:      5.9.0
 
 library
   GHC-Options:      -Wall -fno-warn-orphans
diff --git a/src/ALife/Creatur/Universe.hs b/src/ALife/Creatur/Universe.hs
--- a/src/ALife/Creatur/Universe.hs
+++ b/src/ALife/Creatur/Universe.hs
@@ -160,7 +160,14 @@
 getAgent
   :: (Universe u, Serialize (Agent u))
     => A.AgentId -> StateT u IO (Either String (Agent u))
-getAgent name = withAgentDB (D.lookup name)
+getAgent name = do
+  result <- withAgentDB (D.lookup name)
+  case result of
+    Left msg -> do
+      writeToLog $ "Unable to read " ++ name ++ ": " ++ msg
+      archive name
+    Right _  -> return ()
+  return result
 
 -- | Fetches the agent with the specified ID from the archive.
 getAgentFromArchive
@@ -171,13 +178,12 @@
 -- | Fetches the agents with the specified IDs from the population.
 getAgents
   :: (Universe u, Serialize (Agent u))
-    => [A.AgentId] -> StateT u IO (Either String [Agent u])
+    => [A.AgentId] -> StateT u IO [Agent u]
 getAgents names = do
   selected <- mapM getAgent names
   let (msgs, agents) = partitionEithers selected
-  if null msgs
-    then return $ Right agents
-    else return . Left $ show msgs
+  mapM_ writeToLog msgs
+  return agents
 
 -- | If the agent is alive, adds it to the population (replacing the
 --   the previous copy of that agent, if any). If the agent is dead,
@@ -193,11 +199,16 @@
       if newAgent
          then writeToLog $ A.agentId a ++ " added to population"
          else writeToLog $ A.agentId a ++ " returned to population"
-    else do
-      withAgentDB (D.delete $ A.agentId a)
-      withChecklist $ CL.delete (A.agentId a)
-      writeToLog $ (A.agentId a) ++ " archived and removed from lineup"
+    else archive (A.agentId a)
 
+archive
+  :: (Universe u, Serialize (Agent u))
+    => A.AgentId -> StateT u IO ()
+archive name = do
+  withAgentDB $ D.delete name
+  withChecklist $ CL.delete name
+  writeToLog $ name ++ " archived and removed from lineup"
+
 isNew :: Universe u => A.AgentId -> StateT u IO Bool
 isNew name = fmap (name `notElem`) agentIds
 
@@ -234,13 +245,7 @@
 withAgents
   :: (Universe u, Serialize (Agent u))
     => AgentsProgram u -> [A.AgentId] -> StateT u IO ()
-withAgents program names = do
-  result <- getAgents names
-  case result of
-    Left msg ->
-      writeToLog $ "Unable to read '" ++ show names ++ "': " ++ msg
-    Right as ->
-      program as >>= mapM_ store
+withAgents program names = getAgents names >>= program >>= mapM_ store
 
 -- | Returns the current lineup of (living) agents in the universe.
 --   Note: Check for @'endOfRound'@ and call @'refreshLineup'@ if needed
