diff --git a/include/behaviortree_cpp/actions/script_node.h b/include/behaviortree_cpp/actions/script_node.h
index 3ab0fe0f6..a313a424a 100644
--- a/include/behaviortree_cpp/actions/script_node.h
+++ b/include/behaviortree_cpp/actions/script_node.h
@@ -31,7 +31,7 @@ class ScriptNode : public SyncActionNode
 
   static PortsList providedPorts()
   {
-    return {InputPort("code", "Piece of code that can be parsed")};
+    return {InputPort<std::string>("code", "Piece of code that can be parsed")};
   }
 
 private:
diff --git a/include/behaviortree_cpp/basic_types.h b/include/behaviortree_cpp/basic_types.h
index 4c179e34e..4243c39c2 100644
--- a/include/behaviortree_cpp/basic_types.h
+++ b/include/behaviortree_cpp/basic_types.h
@@ -61,6 +61,11 @@ using StringView = std::string_view;
 // vector of key/value pairs
 using KeyValueVector = std::vector<std::pair<std::string, std::string>>;
 
+
+struct AnyTypeAllowed
+{};
+
+
 /**
  * convertFromString is used to convert a string into a custom type.
  *
@@ -142,6 +147,11 @@ inline StringConverter GetAnyFromStringFunctor()
   {
     return [](StringView str) { return Any(str); };
   }
+  else if constexpr(std::is_same_v<BT::AnyTypeAllowed, T> ||
+                    std::is_enum_v<T>)
+  {
+    return {};
+  }
   else {
     return [](StringView str) { return Any(convertFromString<T>(str)); };
   }
@@ -265,9 +275,6 @@ using Result = Expected<std::monostate>;
 [[nodiscard]]
 bool IsAllowedPortName(StringView str);
 
-struct AnyTypeAllowed
-{};
-
 class TypeInfo
 {
 public:
diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp
index 3bc73f2ba..8067ae595 100644
--- a/src/xml_parsing.cpp
+++ b/src/xml_parsing.cpp
@@ -636,7 +636,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
 
   const TreeNodeManifest* manifest = nullptr;
 
-  auto manifest_it =  factory.manifests().find(type_ID);
+  auto manifest_it = factory.manifests().find(type_ID);
   if(manifest_it != factory.manifests().end())
   {
     manifest = &manifest_it->second;
@@ -647,8 +647,40 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
   {
     if (IsAllowedPortName(att->Name()))
     {
-      const std::string attribute_name = att->Name();
-      port_remap[attribute_name] = att->Value();
+      const std::string port_name = att->Name();
+      const std::string port_value = att->Value();
+
+      if(manifest)
+      {
+        auto port_model_it = manifest->ports.find(port_name);
+        if(port_model_it == manifest->ports.end())
+        {
+          throw RuntimeError(StrCat("a port with name [", port_name,
+                                    "] is found in the XML, but not in the providedPorts()"));
+        }
+        else {
+          const auto& port_model = port_model_it->second;
+          bool is_blacbkboard = port_value.size() >= 3 &&
+                                port_value.front() == '{' &&
+                                port_value.back() == '}';
+          // let's test already if conversion is possible
+          if(!is_blacbkboard && port_model.converter() && port_model.isStronglyTyped())
+          {
+            // This may throw
+            try {
+              port_model.converter()(port_value);
+            }
+            catch(std::exception& ex)
+            {
+              auto msg = StrCat("The port with name \"", port_name, "\" and value \"", port_value,
+                                "\" can not be converted to ", port_model.typeName());
+              throw LogicError(msg);
+            }
+          }
+        }
+      }
+
+      port_remap[port_name] = port_value;
     }
   }
 
diff --git a/tests/gtest_ports.cpp b/tests/gtest_ports.cpp
index 0efbb4cc8..7a8a14f8a 100644
--- a/tests/gtest_ports.cpp
+++ b/tests/gtest_ports.cpp
@@ -533,8 +533,32 @@ TEST(PortTest, DefaultInputStrings)
   ASSERT_EQ(status, NodeStatus::SUCCESS);
 }
 
+struct TestStruct
+{
+  int a;
+  double b;
+  std::string c;
+};
 
-TEST(PortTest, Default_Issues_767_768)
+class NodeWithDefaultNullptr : public SyncActionNode
+{
+public:
+  NodeWithDefaultNullptr(const std::string& name, const NodeConfig& config) :
+      SyncActionNode(name, config) {}
+
+  NodeStatus tick() override
+  {
+    return NodeStatus::SUCCESS;
+  }
+
+  static PortsList providedPorts()
+  {
+    return {BT::InputPort< std::shared_ptr<TestStruct> >("input", nullptr, "default value is nullptr")};
+  }
+};
+
+
+TEST(PortTest, Default_Issues_767)
 {
   using namespace BT;
 
@@ -545,4 +569,29 @@ TEST(PortTest, Default_Issues_767_768)
   ASSERT_NO_THROW(auto p = InputPort<std::shared_ptr<std::string>>("ptr_B", nullptr, "default nullptr"));
 }
 
+TEST(PortTest, DefaultWronglyOverriden)
+{
+  BT::BehaviorTreeFactory factory;
+  factory.registerNodeType<NodeWithDefaultNullptr>("NodeWithDefaultNullptr");
+
+  std::string xml_txt_wrong = R"(
+    <root BTCPP_format="4" >
+      <BehaviorTree>
+        <NodeWithDefaultNullptr input=""/>
+      </BehaviorTree>
+    </root>)";
+
+  std::string xml_txt_correct = R"(
+    <root BTCPP_format="4" >
+      <BehaviorTree>
+        <NodeWithDefaultNullptr/>
+      </BehaviorTree>
+    </root>)";
 
+  // this should throw, because we are NOT using the default, 
+  // but overriding it with an empty string instead.
+  // See issue 768 for reference
+  ASSERT_ANY_THROW( auto tree = factory.createTreeFromText(xml_txt_wrong));
+  // This is correct
+  ASSERT_NO_THROW( auto tree = factory.createTreeFromText(xml_txt_correct));
+}