diff --git a/src/language/ast/ASTNodeDataType.hpp b/src/language/ast/ASTNodeDataType.hpp
index 46b76406b03957117e41c3904a1221207de5340f..98dfaecf8dc06da4b0b42090fe9ea9bd411ddc50 100644
--- a/src/language/ast/ASTNodeDataType.hpp
+++ b/src/language/ast/ASTNodeDataType.hpp
@@ -96,7 +96,7 @@ class ASTNodeDataType
   ASTNodeDataType& operator=(ASTNodeDataType&&) = default;
 
   template <DataType data_type>
-  static ASTNodeDataType
+  [[nodiscard]] static ASTNodeDataType
   build()
   {
     static_assert(data_type != tuple_t, "tuple_t requires sub_type");
@@ -109,17 +109,18 @@ class ASTNodeDataType
   }
 
   template <DataType data_type>
-  static ASTNodeDataType
+  [[nodiscard]] static ASTNodeDataType
   build(const ASTNodeDataType& content_type)
   {
     static_assert((data_type == tuple_t) or (data_type == typename_t),
                   "incorrect data_type construction: cannot have content");
+    Assert(content_type != ASTNodeDataType::undefined_t);
 
     return ASTNodeDataType{data_type, content_type};
   }
 
   template <DataType data_type>
-  static ASTNodeDataType
+  [[nodiscard]] static ASTNodeDataType
   build(const size_t dimension)
   {
     static_assert((data_type == vector_t), "incorrect data_type construction: cannot have dimension");
@@ -127,7 +128,7 @@ class ASTNodeDataType
   }
 
   template <DataType data_type>
-  static ASTNodeDataType
+  [[nodiscard]] static ASTNodeDataType
   build(const std::string& type_name)
   {
     static_assert((data_type == type_id_t), "incorrect data_type construction: cannot provide name of type");
@@ -135,10 +136,15 @@ class ASTNodeDataType
   }
 
   template <DataType data_type>
-  static ASTNodeDataType
+  [[nodiscard]] static ASTNodeDataType
   build(const std::vector<std::shared_ptr<const ASTNodeDataType>>& list_of_types)
   {
     static_assert((data_type == list_t), "incorrect data_type construction: cannot provide a list of data types");
+
+    for (auto i : list_of_types) {
+      Assert(i->m_data_type != ASTNodeDataType::undefined_t, "cannot build a type list containing undefined types");
+    }
+
     return ASTNodeDataType{data_type, list_of_types};
   }
 
diff --git a/src/language/ast/ASTNodeDataTypeBuilder.cpp b/src/language/ast/ASTNodeDataTypeBuilder.cpp
index 105556b835aa849011bba6d99065df8e996a62b5..dcde89f1c99ef6ad6565ec287475b18aa20c2749 100644
--- a/src/language/ast/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ast/ASTNodeDataTypeBuilder.cpp
@@ -7,7 +7,7 @@
 #include <language/utils/SymbolTable.hpp>
 #include <utils/PugsAssert.hpp>
 
-ASTNodeDataType
+void
 ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNode& name_node) const
 {
   ASTNodeDataType data_type;
@@ -116,7 +116,7 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo
   }
 
   Assert(data_type != ASTNodeDataType::undefined_t);
-  return data_type;
+  type_node.m_data_type = ASTNodeDataType::build<ASTNodeDataType::typename_t>(data_type);
 }
 
 void
@@ -160,8 +160,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
         auto& name_node = *(n.children[0]);
         auto& type_node = *(n.children[1]);
 
-        type_node.m_data_type =
-          ASTNodeDataType::build<ASTNodeDataType::typename_t>(_buildDeclarationNodeDataTypes(type_node, name_node));
+        _buildDeclarationNodeDataTypes(type_node, name_node);
         n.m_data_type = ASTNodeDataType::build<ASTNodeDataType::void_t>();
       } else if (n.is_type<language::fct_declaration>()) {
         n.children[0]->m_data_type = ASTNodeDataType::build<ASTNodeDataType::function_t>();
@@ -205,28 +204,9 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
 
         auto simple_type_allocator = [&](const ASTNode& type_node, ASTNode& symbol_node) {
           Assert(symbol_node.is_type<language::name>());
-          ASTNodeDataType data_type;
-          if (type_node.is_type<language::B_set>()) {
-            data_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>();
-          } else if (type_node.is_type<language::Z_set>()) {
-            data_type = ASTNodeDataType::build<ASTNodeDataType::int_t>();
-          } else if (type_node.is_type<language::N_set>()) {
-            data_type = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>();
-          } else if (type_node.is_type<language::R_set>()) {
-            data_type = ASTNodeDataType::build<ASTNodeDataType::double_t>();
-          } else if (type_node.is_type<language::vector_type>()) {
-            data_type = getVectorDataType(type_node);
-          } else if (type_node.is_type<language::string_type>()) {
-            data_type = ASTNodeDataType::build<ASTNodeDataType::string_t>();
-          }
-
-          // LCOV_EXCL_START
-          if (data_type == ASTNodeDataType::undefined_t) {
-            throw ParseError("invalid parameter type", type_node.begin());
-          }
-          // LCOV_EXCL_STOP
+          const ASTNodeDataType& data_type = type_node.m_data_type.contentType();
 
-          symbol_node.m_data_type   = data_type;
+          symbol_node.m_data_type   = type_node.m_data_type.contentType();
           const std::string& symbol = symbol_node.string();
 
           std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table;
diff --git a/src/language/ast/ASTNodeDataTypeBuilder.hpp b/src/language/ast/ASTNodeDataTypeBuilder.hpp
index 93643c82d80c9c222cb12b482416a661ff20fb31..be2c35adfb2ab81479ef27d385be880b35b0538c 100644
--- a/src/language/ast/ASTNodeDataTypeBuilder.hpp
+++ b/src/language/ast/ASTNodeDataTypeBuilder.hpp
@@ -6,7 +6,7 @@
 class ASTNodeDataTypeBuilder
 {
  private:
-  ASTNodeDataType _buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNode& name_node) const;
+  void _buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNode& name_node) const;
 
   void _buildNodeDataTypes(ASTNode& node) const;
 
diff --git a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp
index de442dd57789dfc0072d7ef5d42f899ecd77cb05..af8b1cbc0b4ca138f86601755493e90a089ff0c2 100644
--- a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp
+++ b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp
@@ -330,26 +330,10 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
 
   std::unique_ptr function_processor = this->_buildArgumentConverter(function_descriptor, node);
 
-  auto add_component_expression = [&](ASTNode& expression_node, ASTNode& domain_node) {
-    ASTNodeDataType return_value_type;
+  auto add_component_expression = [&](ASTNode& expression_node, const ASTNode& image_domain_node) {
+    Assert(image_domain_node.m_data_type == ASTNodeDataType::typename_t);
 
-    ASTNode& image_domain_node = domain_node;
-
-    if (image_domain_node.is_type<language::B_set>()) {
-      return_value_type = ASTNodeDataType::build<ASTNodeDataType::bool_t>();
-    } else if (image_domain_node.is_type<language::Z_set>()) {
-      return_value_type = ASTNodeDataType::build<ASTNodeDataType::int_t>();
-    } else if (image_domain_node.is_type<language::N_set>()) {
-      return_value_type = ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>();
-    } else if (image_domain_node.is_type<language::R_set>()) {
-      return_value_type = ASTNodeDataType::build<ASTNodeDataType::double_t>();
-    } else if (image_domain_node.is_type<language::vector_type>()) {
-      return_value_type = getVectorDataType(image_domain_node);
-    } else if (image_domain_node.is_type<language::string_type>()) {
-      return_value_type = ASTNodeDataType::build<ASTNodeDataType::string_t>();
-    }
-
-    Assert(return_value_type != ASTNodeDataType::undefined_t);
+    const ASTNodeDataType return_value_type = image_domain_node.m_data_type.contentType();
 
     if ((return_value_type == ASTNodeDataType::vector_t) and (return_value_type.dimension() == 1)) {
       ASTNodeNaturalConversionChecker{expression_node, ASTNodeDataType::build<ASTNodeDataType::double_t>()};
@@ -364,6 +348,9 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
   ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1];
   ASTNode& function_expression   = *function_descriptor.definitionNode().children[1];
 
+  Assert(function_image_domain.m_data_type == ASTNodeDataType::typename_t);
+  const ASTNodeDataType function_return_type = function_image_domain.m_data_type.contentType();
+
   if (function_image_domain.is_type<language::vector_type>()) {
     ASTNodeDataType vector_type = getVectorDataType(function_image_domain);
 
diff --git a/src/language/ast/ASTSymbolInitializationChecker.cpp b/src/language/ast/ASTSymbolInitializationChecker.cpp
index 4245912037c969ae63f5e970ecd1d68a338e7179..0e4d441fe590fb16534987bc1683ee2aadf0e98e 100644
--- a/src/language/ast/ASTSymbolInitializationChecker.cpp
+++ b/src/language/ast/ASTSymbolInitializationChecker.cpp
@@ -37,8 +37,10 @@ ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
       if (node.children.size() == 4) {
         ASTNode& decl_name_list_node = *node.children[0];
         ASTNode& def_name_list_node  = *node.children[2];
-        Assert(def_name_list_node.is_type<language::name_list>());
-        ASTNode& expression_list_node = *node.children[3];
+
+        if (not def_name_list_node.is_type<language::name_list>()) {
+          throw ParseError("expecting a list of identifiers", std::vector{def_name_list_node.begin()});
+        }
 
         if (decl_name_list_node.children.size() != def_name_list_node.children.size()) {
           std::ostringstream os;
@@ -47,6 +49,8 @@ ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
           throw ParseError(os.str(), std::vector{def_name_list_node.begin()});
         }
 
+        ASTNode& expression_list_node = *node.children[3];
+
         this->_checkSymbolInitialization(expression_list_node);
         for (size_t i = 0; i < decl_name_list_node.children.size(); ++i) {
           check_correct_name_in_definition(*decl_name_list_node.children[i], *def_name_list_node.children[i]);
diff --git a/tests/test_ASTNodeDataType.cpp b/tests/test_ASTNodeDataType.cpp
index 9d1f55234d849a95ebb9fb2b33963b74aed575fb..21f5c08bfbe6399b8d5a27ea2c33b56e84f78232 100644
--- a/tests/test_ASTNodeDataType.cpp
+++ b/tests/test_ASTNodeDataType.cpp
@@ -260,4 +260,11 @@ TEST_CASE("ASTNodeDataType", "[language]")
                                       ASTNodeDataType::build<ASTNodeDataType::type_id_t>("bar")));
     }
   }
+
+#ifndef NDEBUG
+  SECTION("errors")
+  {
+    REQUIRE_THROWS_AS(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(undefined_dt), AssertError);
+  }
+#endif   // NDEBUG
 }
diff --git a/tests/test_ASTNodeNaturalConversionChecker.cpp b/tests/test_ASTNodeNaturalConversionChecker.cpp
index f4921b042fc3227cbb5da28cb66b478781ddf1c5..a9c187551f42d64860569a60b4f3584ac058b963 100644
--- a/tests/test_ASTNodeNaturalConversionChecker.cpp
+++ b/tests/test_ASTNodeNaturalConversionChecker.cpp
@@ -79,7 +79,7 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]")
 
       SECTION("tuple -> string")
       {
-        data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(undefined_dt);
+        data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(double_dt);
         REQUIRE_NOTHROW(ASTNodeNaturalConversionChecker{*data_node, string_dt});
       }
     }