diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index fa94bdca04bc6461df3cd1655f82b67869a01330..b04d23c36f13cb3ad5efc943193433711facd9c8 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -74,6 +74,7 @@ set(SRCS
   base/MainConfig.cxx
   base/RecoParams.cxx
   base/util/StlUtils.cxx
+  base/util/EnumDict.cxx
   base/util/TimingsFormat.cxx
   data/sts/HitfinderPars.cxx
   data/sts/LandauTable.cxx
diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx
index 5c4f42813a387d5b658cbd0ada66a10cf3647e5c..62cb3e269074ce241c27ac4b54ff2adb7fe084fe 100644
--- a/algo/base/Options.cxx
+++ b/algo/base/Options.cxx
@@ -75,7 +75,7 @@ Options::Options(int argc, char** argv)
     ("log-file,L", po::value(&fLogFile)->value_name("<file>"),
       "write log messages to file")
     ("output-types,O", po::value(&fOutputTypes)->multitoken()->value_name("<types>"),
-      "space seperated list of reconstruction output types (hit, digi, ...)")
+      "space seperated list of reconstruction output types (Hit, Tracks, RawDigi, DigiEvent, ...)")
     ("compress-archive", po::bool_switch(&fCompressArchive)->default_value(false), "Enable compression for output archives")
     ("steps", po::value(&fRecoSteps)->multitoken()->default_value({Step::Unpack, Step::DigiTrigger, Step::LocalReco, Step::Tracking})->value_name("<steps>"),
       "space seperated list of reconstruction steps (unpack, digitrigger, localreco, ...)")
diff --git a/algo/base/util/EnumDict.cxx b/algo/base/util/EnumDict.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a0ffd40f360a6bea9e7f3976e08ef7b2c8f44cee
--- /dev/null
+++ b/algo/base/util/EnumDict.cxx
@@ -0,0 +1,20 @@
+/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+#include "EnumDict.h"
+
+#include <sstream>
+
+void cbm::algo::detail::RaiseUnknownEntry(std::string_view str, const std::vector<std::string_view>& validEntries)
+{
+  std::ostringstream oss;
+  oss << "Could not parse '" << str << "'. Valid entries are: ";
+
+  for (size_t i = 0; i < validEntries.size(); ++i) {
+    oss << validEntries[i];
+    if (i != validEntries.size() - 1) {
+      oss << ", ";
+    }
+  }
+  throw std::invalid_argument(oss.str());
+}
diff --git a/algo/base/util/EnumDict.h b/algo/base/util/EnumDict.h
index 9bd598e296d9d36b17dcc27696b7ee8fcb5dbe11..fde2d6d7850590a8c5f089ccad49762dba3c2174 100644
--- a/algo/base/util/EnumDict.h
+++ b/algo/base/util/EnumDict.h
@@ -32,6 +32,18 @@ namespace cbm::algo
 
     template<typename T>
     inline constexpr bool EnumHasDict_v = EnumHasDict<T>::value;
+
+    template<typename T, typename = std::enable_if_t<detail::EnumHasDict_v<T>>>
+    std::vector<std::string_view> ValidEntries()
+    {
+      std::vector<std::string_view> entries;
+      for (const auto& pair : EnumDict<T>) {
+        entries.push_back(pair.first);
+      }
+      return entries;
+    }
+
+    void RaiseUnknownEntry(std::string_view str, const std::vector<std::string_view>& validEntries);
   }  // namespace detail
 
   template<typename T, typename = std::enable_if_t<detail::EnumHasDict_v<T>>>
@@ -112,7 +124,9 @@ namespace std
     is >> str;
     auto maybet = cbm::algo::FromString<T>(str);
 
-    if (!maybet) throw std::invalid_argument("Could not parse " + str + " as Enum");
+    if (!maybet) {
+      cbm::algo::detail::RaiseUnknownEntry(str, cbm::algo::detail::ValidEntries<T>());
+    }
     t = *maybet;
 
     return is;