diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 264d057be5e7bbe5c4afa8d47d6b7e3e90041df0..f36f295862855285a9f9518272adbbfa34dd4c91 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -50,9 +50,35 @@ namespace armarx
         }
     }
 
+    std::string SkillManagerComponentPluginUser::getFirstProviderNameThatHasSkill(const std::string& skillName)
+    {
+        for (const auto& [providerName, providerPrx] : skillProviderMap)
+        {
+            auto allSkills = providerPrx->getSkillDescriptions();
+            for (const auto& [currentSkillName, skillDesc] : allSkills)
+            {
+                if (currentSkillName == skillName)
+                {
+                    return providerName;
+                }
+            }
+        }
+        return "INVALID PROVIDER NAME";
+    }
+
     skills::provider::dto::Execution::Status SkillManagerComponentPluginUser::executeSkill(const skills::manager::dto::SkillExecutionRequest& info, const Ice::Current&)
     {
-        if (auto it = skillProviderMap.find(info.providerName); it != skillProviderMap.end())
+        std::string providerName = "INVALID PROVIDER NAME";
+        if (info.providerName == "*")
+        {
+            providerName = getFirstProviderNameThatHasSkill(info.skillName);
+        }
+        else if(not(info.providerName.empty()))
+        {
+            providerName = info.providerName;
+        }
+
+        if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
         {
             skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
             getProxy(myPrx, -1);
@@ -66,7 +92,8 @@ namespace armarx
         }
         else
         {
-            throw LocalException("Could not execute a skill of provider '" + info.providerName + "' because the provider does not exist.");
+            ARMARX_ERROR << "Could not execute a skill of provider '" + providerName + "' because the provider does not exist.";
+            throw armarx::LocalException("Skill execution failed. Could not execute a skill of provider '" + providerName + "' because the provider does not exist.");
         }
     }
 
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
index c877db612846a6b1f3f08123ac56cdf4128621fb..7e5049c0769e383a5a42966333e0f217192ed661 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
@@ -41,6 +41,9 @@ namespace armarx
         skills::manager::dto::SkillDescriptionMapMap getSkillDescriptions(const Ice::Current &current) override;
         skills::manager::dto::SkillStatusUpdateMapMap getSkillExecutionStatuses(const Ice::Current &current) override;
 
+    protected:
+        std::string getFirstProviderNameThatHasSkill(const std::string& skillName);
+
     private:
         armarx::plugins::SkillManagerComponentPlugin* plugin = nullptr;
 
diff --git a/source/RobotAPI/libraries/skills/provider/Skill.h b/source/RobotAPI/libraries/skills/provider/Skill.h
index 4f1cd612688c5bbb325de2caa53118f14eb9d7fa..fa12b30ebd4d2feb0404a31a2d428682706b7b88 100644
--- a/source/RobotAPI/libraries/skills/provider/Skill.h
+++ b/source/RobotAPI/libraries/skills/provider/Skill.h
@@ -37,6 +37,11 @@ namespace armarx
             Skill(const SkillDescription&);
             virtual ~Skill() = default;
 
+            std::string getSkillId() const
+            {
+                return providerName + "/" + description.skillName;
+            }
+
             /// Override this method with the actual implementation.
             virtual void init(const aron::data::DictPtr& params);
 
@@ -77,7 +82,7 @@ namespace armarx
             manager::dti::SkillManagerInterfacePrx manager = nullptr;
 
             /// the provider that owns this skill. Will be set from provider and is const afterwards
-            std::string providerName = "";
+            std::string providerName = "INVALID PROVIDER NAME";
 
         protected:
             /// Use conditions this way
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
index 74c96a6d3a887a01df54333c438fa18167a26947..39f333300ef32669df44048b619ce2142bee2216 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
@@ -73,7 +73,7 @@ namespace armarx
         }
 
         std::string skillName = skill->description.skillName;
-        if (connected)
+        if (connected) // TODO: fix so that skills can be added anytime!!!
         {
             ARMARX_WARNING << "The SkillProvider already registered to a manager. The skill '" + skillName + "' therefore cannot be added anymore. Please only add skills in the onInit method.";
             return;
@@ -151,7 +151,7 @@ namespace armarx
         {
             std::shared_lock l(skillsMutex);
             std::string skillName = info.skillName;
-            ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0);
+            ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0) << "\nThe names are: " << VAROUT(skillName) << ", " << VAROUT(getName());
 
             // get reference of the wrapper
             auto& wrapper = skillImplementations.at(skillName);
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
index 700a3e741706d1db98633636a0f4ede01ed21918..9193874f143a99e537b20ac7cd76bd511c23a09a 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
@@ -11,9 +11,10 @@ namespace armarx
         {
         }
 
-        Skill::Status SkillProxy::execute(const aron::data::DictPtr& params, const Skill::CallbackT& callback)
+        Skill::Status SkillProxy::execute(const std::string& clientId, const aron::data::DictPtr& params)
         {
             skills::manager::dto::SkillExecutionRequest req;
+            req.clientId = clientId;
             req.params = params->toAronDictDTO();
             req.providerName = providerName;
             req.skillName = skillName;
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.h b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
index 824c2c2fb075030ebf13622f5cc0bb88f71ee742..9ed8250692e77ac8ea2489359834d885199f90b3 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
@@ -6,12 +6,13 @@ namespace armarx
 {
     namespace skills
     {
+        /* Manages the remote execution of a skill and converts the return type to the Skill::Status enum class */
         class SkillProxy : public armarx::Logging
         {
         public:
             SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager, const std::string& skillProviderName, const std::string& skillName);
 
-            Skill::Status execute(const aron::data::DictPtr& params, const Skill::CallbackT& callback = [](const aron::data::DictPtr& returnValue) { (void) returnValue; });
+            Skill::Status execute(const std::string& clientId, const aron::data::DictPtr& params);
 
         private:
             manager::dti::SkillManagerInterfacePrx manager;