diff --git a/algo/base/RecoParams.h b/algo/base/RecoParams.h
index ed9a7e79f27f0108727865e931f3c6aa49d22d50..184e78a1e5cae8b4f987b1aaff20a982ea18ceb2 100644
--- a/algo/base/RecoParams.h
+++ b/algo/base/RecoParams.h
@@ -8,6 +8,7 @@
 
 #include "Prelude.h"
 #include "config/Property.h"
+#include "util/SerializableEnum.h"
 
 namespace cbm::algo
 {
@@ -16,12 +17,12 @@ namespace cbm::algo
    * @brief RecoParams contains all parameters to configure reconstruction
    */
   struct RecoParams {
-    enum SortMode : u8
+    enum class SortMode : u8
     {
-      SortBlockSort        = 0,
-      SortCUBSegmentedSort = 1,
+      BlockSort        = 0,
+      CUBSegmentedSort = 1,
     };
-    enum UnpackMode : u8
+    enum class UnpackMode : u8
     {
       CPU,
       XPU,
@@ -96,6 +97,27 @@ namespace cbm::algo
     static constexpr auto Properties = std::make_tuple(config::Property(&RecoParams::sts, "sts", "STS reco settings"));
   };
 
+  template<>
+  struct EnumIsSerializable<RecoParams::SortMode> : std::true_type {
+  };
+
+  template<>
+  inline const EnumDict_t<RecoParams::SortMode>& EnumDict<RecoParams::SortMode> = {
+    {"BlockSort", RecoParams::SortMode::BlockSort},
+    {"CUBSegmentedSort", RecoParams::SortMode::CUBSegmentedSort},
+  };
+
+  template<>
+  struct EnumIsSerializable<RecoParams::UnpackMode> : std::true_type {
+  };
+
+  template<>
+  inline const EnumDict_t<RecoParams::UnpackMode>& EnumDict<RecoParams::UnpackMode> = {
+    {"CPU", RecoParams::UnpackMode::CPU},
+    {"XPU", RecoParams::UnpackMode::XPU},
+  };
+
+
 };  // namespace cbm::algo
 
 #endif  // CBM_ALGO_BASE_RECOPARAMS_H
diff --git a/algo/base/config/Yaml.h b/algo/base/config/Yaml.h
index 1697a23be1de0876364f4868198479fcd186d40c..cbdd7a2f9a0847167958c461615ac11cea41d6d8 100644
--- a/algo/base/config/Yaml.h
+++ b/algo/base/config/Yaml.h
@@ -13,6 +13,7 @@
 #include "BaseTypes.h"
 #include "Prelude.h"
 #include "Property.h"
+#include "util/SerializableEnum.h"
 
 namespace cbm::algo::config
 {
@@ -28,10 +29,15 @@ namespace cbm::algo::config
   {
     using Type = std::remove_cv_t<std::remove_reference_t<T>>;
 
+    static_assert(!IsEnum<T> || EnumIsSerializable<Type>::value, "Enum must be serializable");
+
+
     // TODO: error handling
     if constexpr (IsBaseType<Type>) { return node.as<Type>(); }
     else if constexpr (IsEnum<Type>) {
-      return static_cast<Type>(node.as<std::underlying_type_t<Type>>());
+      std::optional<T> maybet = FromString<T>(node.as<std::string>());
+      if (!maybet) { throw std::runtime_error(fmt::format("Invalid enum value: {}", node.as<std::string>())); }
+      return *maybet;
     }
     else if constexpr (IsVector<Type>) {
       Type vector;
@@ -117,7 +123,12 @@ namespace cbm::algo::config
     template<typename T>
     void DoDump(const T& object, YAML::Emitter& ss, std::optional<YAML::EMITTER_MANIP> formatEntries = {})
     {
+      static_assert(!IsEnum<T> || EnumIsSerializable<T>::value, "Enum must be serializable");
+
       if constexpr (IsBaseType<T>) { ss << object; }
+      else if constexpr (IsEnum<T>) {
+        ss << ToString<T>(object);
+      }
       else if constexpr (IsVector<T> || IsArray<T>) {
         ss << YAML::BeginSeq;
         for (const auto& element : object) {
diff --git a/algo/params/RecoParams.yaml b/algo/params/RecoParams.yaml
index b69e5db5ea563ddfef1646a202181e773d9aecbd..e23a50bc39a83e139d64dc15c969e5d383929595 100644
--- a/algo/params/RecoParams.yaml
+++ b/algo/params/RecoParams.yaml
@@ -1,10 +1,8 @@
 ---
 sts:
-  # 0: block_sort, 1: cub
-  digiSortMode: 0
-  clusterSortMode: 0
-  # 0: cpu, 1: xpu
-  unpackMode: 0
+  digiSortMode: BlockSort
+  clusterSortMode: BlockSort
+  unpackMode: CPU
   findClustersMultiKernels: 1
   timeCutDigiAbs: -1
   timeCutDigiSig: 3