diff --git a/include/aidge/utils/StaticAttributes.hpp b/include/aidge/utils/StaticAttributes.hpp
index 248fef3f3ed729f588e2c30aa0c9de5995cab229..fb800cffbcff5d4113961f8e62977417336f2cb8 100644
--- a/include/aidge/utils/StaticAttributes.hpp
+++ b/include/aidge/utils/StaticAttributes.hpp
@@ -18,6 +18,7 @@
 #include <typeinfo>
 
 #include "aidge/utils/Attributes.hpp"
+#include "aidge/utils/Utils.hpp"
 
 namespace Aidge {
 /**
@@ -93,7 +94,7 @@ public:
             }
         }
 
-        assert(false && "attribute not found");
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name);
     }
 
     template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
@@ -103,7 +104,7 @@ public:
                 return reinterpret_cast<R&>(std::get<SIZE-1>(mAttrs));
             }
             else {
-                assert(false && "wrong attribute type");
+                AIDGE_THROW_OR_ABORT(std::runtime_error, "wrong type for attribute with index %lu", i);
             }
         }
         else {
@@ -113,7 +114,7 @@ public:
 
     template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
     [[noreturn]] constexpr typename std::enable_if<(SIZE == 0), R&>::type getAttr(std::size_t /*i*/) {
-        assert(false && "attribute not found");
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
     }
 
     template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
@@ -127,10 +128,8 @@ public:
     }
 
     template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
-    /*[[noreturn]]*/ constexpr typename std::enable_if<(SIZE == 0), const std::type_info&>::type getAttrType(std::size_t /*i*/) const {
-        assert(false && "attribute not found");
-        return typeid(void);  // avoid MSVC error C4716: "must return a value", despite [[noreturn]] attribute
-                              // [[noreturn]] attribute is removed otherwise GCC complains because there is a return.
+    [[noreturn]] constexpr typename std::enable_if<(SIZE == 0), const std::type_info&>::type getAttrType(std::size_t /*i*/) const {
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
     }
 
     constexpr const std::tuple<T...>& getStaticAttributes() const {
@@ -159,7 +158,7 @@ public:
             }
         }
 
-        assert(false && "attribute not found");
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name.c_str());
     }
 
     std::set<std::string> getAttrsName() const override final {
@@ -179,7 +178,8 @@ public:
                 return py::detail::accessor_policies::tuple_item::get(py::cast(mAttrs), static_cast<py::size_t>(i));
             }
         }
-        throw py::value_error("Attribute : " + name + " does not exist." );
+
+        AIDGE_THROW_OR_ABORT(py::value_error, "attribute \"%s\" not found", name.c_str());
     };
     #endif
 
diff --git a/include/aidge/utils/Utils.hpp b/include/aidge/utils/Utils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c0c03c82ff252b6175d3c9bbe5395bb05127c9f
--- /dev/null
+++ b/include/aidge/utils/Utils.hpp
@@ -0,0 +1,37 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+#ifndef AIDGE_UTILS_H_
+#define AIDGE_UTILS_H_
+
+#include <cstdio>
+
+#ifdef NO_EXCEPTIONS
+#define AIDGE_THROW_OR_ABORT(ex, ...) \
+do { std::printf(__VA_ARGS__); std::abort(); } while (false)
+#else
+#include <stdexcept>
+#define AIDGE_THROW_OR_ABORT(ex, ...) \
+do { \
+    int n = 128; \
+    std::unique_ptr<char[]> formatted; \
+    formatted.reset(new char[n]); \
+    const int len = std::snprintf(formatted.get(), n, __VA_ARGS__); \
+    if (len >= n) { \
+        formatted.reset(new char[len + 1]); \
+        std::snprintf(formatted.get(), len + 1, __VA_ARGS__); \
+    }; \
+    throw ex(formatted.get()); \
+} while (false)
+#endif
+
+#endif //AIDGE_UTILS_H_
\ No newline at end of file
diff --git a/unit_tests/operator/Test_GenericOperator.cpp b/unit_tests/operator/Test_GenericOperator.cpp
index c7b447e914b391c0b137e49cf7aed27703d4fcc0..8d634cc3a105c423b54b6003f41204aeb1fc5335 100644
--- a/unit_tests/operator/Test_GenericOperator.cpp
+++ b/unit_tests/operator/Test_GenericOperator.cpp
@@ -77,7 +77,7 @@ TEST_CASE("[core/operators] GenericOp(add & get attributes)", "[Operator]") {
     }
 }
 
-TEST_CASE("[core/operator] GenericOp(type check)", "[.ass]") {
+TEST_CASE("[core/operator] GenericOp(type check)", "[Operator]") {
     SECTION("WRONG TYPE FOR GETTER") {
         GenericOperator_Op Testop("TestOp", 1, 1, 1);
         Testop.addAttr<long>("longAttr", 3);
diff --git a/unit_tests/utils/Test_StaticAttributes.cpp b/unit_tests/utils/Test_StaticAttributes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36c2e0454b415e1cb25cc3581016530a372b9e65
--- /dev/null
+++ b/unit_tests/utils/Test_StaticAttributes.cpp
@@ -0,0 +1,48 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <catch2/catch_test_macros.hpp>
+
+#include <string>
+#include <vector>
+
+#include "aidge/utils/StaticAttributes.hpp"
+
+using namespace Aidge;
+
+enum class TestAttr { a, b, c, d };
+
+namespace {
+template <>
+const char *const EnumStrings<TestAttr>::data[] = {
+    "a",
+    "b",
+    "c",
+    "d"
+};
+}
+
+using Attributes_ = StaticAttributes<TestAttr, int, float, std::string, std::vector<bool>>;
+template <TestAttr e>
+using attr = typename Attributes_::template attr<e>;
+
+TEST_CASE("[core/attributes] StaticAttribute") {
+    SECTION("TestAttr") {
+        StaticAttributes<TestAttr, int, float, std::string, std::vector<bool>> attrs(
+            attr<TestAttr::a>(42),
+            attr<TestAttr::b>(18.75),
+            attr<TestAttr::c>("test"),
+            attr<TestAttr::d>({true, false, true}));
+
+        REQUIRE(attrs.getAttr<int>("a") == 42);
+        REQUIRE_THROWS(attrs.getAttr<int>("inexistant"));
+    }
+}