diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
index 15efc34f03a50b46b457956de91eb97e3ca23d60..1e8f298029912c1eab459cd5d285ba0a8e144ff5 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
@@ -26,6 +26,7 @@
 
 #include <SimoxUtility/algorithm/string.h>
 
+#include <RobotAPI/libraries/armem/client/Prediction.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/ice_conversions_templates.h>
@@ -226,12 +227,12 @@ namespace armarx
     armem::prediction::data::PredictionResult
     ExampleMemory::predictSingle(const armem::prediction::data::PredictionRequest& request)
     {
-        armem::prediction::data::PredictionResult result;
+        armem::client::PredictionResult result;
 
-        std::string engine = request.settings.predictionEngine;
+        std::string engine = request.settings.predictionEngineID;
         if (engine.empty() || engine == "Latest")
         {
-            auto boID = fromIce<armem::MemoryID>(request.memoryID);
+            auto boID = fromIce<armem::MemoryID>(request.snapshotID);
             armem::client::QueryBuilder builder;
             builder.latestEntitySnapshot(boID);
             auto queryResult =
@@ -246,34 +247,35 @@ namespace armarx
                                         ? latest->getInstance(boID)
                                         : latest->getInstance(latest->getInstanceIndices().at(0));
                     result.success = true;
-                    result.prediction = instance.data()->toAronDictDTO();
+                    result.snapshotID = boID;
+                    result.prediction = instance.data();
                 }
                 else
                 {
                     result.success = false;
-                    result.errorMessage =
-                        "Could not find entity referenced by MemoryID " + boID.str();
+                    result.errorMessage <<
+                        "Could not find entity referenced by MemoryID " << boID;
                 }
             }
             else
             {
                 result.success = false;
-                result.errorMessage = "Could not find entity referenced by MemoryID " + boID.str();
+                result.errorMessage << "Could not find entity referenced by MemoryID " << boID;
             }
         }
         else
         {
             result.success = false;
-            result.errorMessage = "This memory does not support the prediction engine " + engine;
+            result.errorMessage << "This memory does not support the prediction engine \"" << engine << "\"";
         }
 
-        return result;
+        return result.toIce();
     }
 
     armem::prediction::data::PredictionEngineSeq
     ExampleMemory::getAvailableEngines()
     {
-        return {"Latest"};
+        return {{"Latest"}};
     }
 
     // REMOTE GUI
diff --git a/source/RobotAPI/interface/armem/prediction.ice b/source/RobotAPI/interface/armem/prediction.ice
index b4f0efabe1df20ed3ca1ad4d5c3893b7d618e739..f42535928e434be36702a949f9929246a8f08f7b 100644
--- a/source/RobotAPI/interface/armem/prediction.ice
+++ b/source/RobotAPI/interface/armem/prediction.ice
@@ -11,19 +11,24 @@ module armarx
         {
             module data
             {
-                sequence<string> PredictionEngineSeq;
+                // Holds properties of a prediction engine identified by its engineID.
+                struct PredictionEngine
+                {
+                    string engineID;
+                }
+                sequence<PredictionEngine> PredictionEngineSeq;
 
                 // Settings to use for a given prediction (e.g. which engine to use)
                 struct PredictionSettings
                 {
-                    string predictionEngine = "";
+                    string predictionEngineID = "";
                 };
 
                 // A single request for a prediction from a memory.
                 // The timestamp to request the prediction for is in the MemoryID.
                 struct PredictionRequest
                 {
-                    armem::data::MemoryID memoryID;
+                    armem::data::MemoryID snapshotID;
                     PredictionSettings settings;
                 }
                 sequence<PredictionRequest> PredictionRequestSeq;
@@ -35,6 +40,7 @@ module armarx
                     bool success = false;
                     string errorMessage;
 
+                    armem::data::MemoryID snapshotID;
                     aron::data::dto::Dict prediction;
                 }
                 sequence<PredictionResult> PredictionResultSeq;
diff --git a/source/RobotAPI/libraries/armem/client/Prediction.cpp b/source/RobotAPI/libraries/armem/client/Prediction.cpp
index fa7429f2c9a7b2e0100e56688f396bf358bcb09a..f58649a457fc8117309ceaf5426a0a84540f35f5 100644
--- a/source/RobotAPI/libraries/armem/client/Prediction.cpp
+++ b/source/RobotAPI/libraries/armem/client/Prediction.cpp
@@ -28,6 +28,17 @@
 
 namespace armarx::armem::client
 {
+    PredictionEngine
+    PredictionEngine::fromIce(const armem::prediction::data::PredictionEngine& ice)
+    {
+        return armarx::fromIce<PredictionEngine>(ice);
+    }
+
+    armem::prediction::data::PredictionEngine
+    PredictionEngine::toIce() const
+    {
+        return armarx::toIce<armem::prediction::data::PredictionEngine>(*this);
+    }
 
     PredictionSettings
     PredictionSettings::fromIce(const armem::prediction::data::PredictionSettings& ice)
@@ -65,29 +76,41 @@ namespace armarx::armem::client
         return armarx::toIce<armem::prediction::data::PredictionResult>(*this);
     }
 
+    void
+    toIce(armem::prediction::data::PredictionEngine& ice, const PredictionEngine& engine)
+    {
+        ice.engineID = engine.engineID;
+    }
+
+    void
+    fromIce(const armem::prediction::data::PredictionEngine& ice, PredictionEngine& engine)
+    {
+        engine.engineID = ice.engineID;
+    }
+
     void
     toIce(armem::prediction::data::PredictionSettings& ice, const PredictionSettings& settings)
     {
-        ice.predictionEngine = settings.predictionEngine;
+        ice.predictionEngineID = settings.predictionEngineID;
     }
 
     void
     fromIce(const armem::prediction::data::PredictionSettings& ice, PredictionSettings& settings)
     {
-        settings.predictionEngine = ice.predictionEngine;
+        settings.predictionEngineID = ice.predictionEngineID;
     }
 
     void
     toIce(armem::prediction::data::PredictionRequest& ice, const PredictionRequest& request)
     {
-        toIce(ice.memoryID, request.memoryID);
+        toIce(ice.snapshotID, request.snapshotID);
         toIce(ice.settings, request.predictionSettings);
     }
 
     void
     fromIce(const armem::prediction::data::PredictionRequest& ice, PredictionRequest& request)
     {
-        fromIce(ice.memoryID, request.memoryID);
+        fromIce(ice.snapshotID, request.snapshotID);
         fromIce(ice.settings, request.predictionSettings);
     }
 
@@ -95,7 +118,8 @@ namespace armarx::armem::client
     toIce(armem::prediction::data::PredictionResult& ice, const PredictionResult& result)
     {
         ice.success = result.success;
-        ice.errorMessage = result.errorMessage;
+        ice.errorMessage = result.errorMessage.str();
+        toIce(ice.snapshotID, result.snapshotID);
         ice.prediction = result.prediction->toAronDictDTO();
     }
 
@@ -103,7 +127,8 @@ namespace armarx::armem::client
     fromIce(const armem::prediction::data::PredictionResult& ice, PredictionResult& result)
     {
         result.success = ice.success;
-        result.errorMessage = ice.errorMessage;
+        result.errorMessage.str(ice.errorMessage);
+        fromIce(ice.snapshotID, result.snapshotID);
         result.prediction = aron::data::Dict::FromAronDictDTO(ice.prediction);
     }
 
diff --git a/source/RobotAPI/libraries/armem/client/Prediction.h b/source/RobotAPI/libraries/armem/client/Prediction.h
index 8408911415af7725ed3fff6e176f1f42b688f2bb..a1538758519228b93e4c6f95e131eed6c7fe9bad 100644
--- a/source/RobotAPI/libraries/armem/client/Prediction.h
+++ b/source/RobotAPI/libraries/armem/client/Prediction.h
@@ -28,9 +28,18 @@
 
 namespace armarx::armem::client
 {
+
+    struct PredictionEngine
+    {
+        std::string engineID;
+
+        static PredictionEngine fromIce(const armem::prediction::data::PredictionEngine& ice);
+        armem::prediction::data::PredictionEngine toIce() const;
+    };
+
     struct PredictionSettings
     {
-        std::string predictionEngine;
+        std::string predictionEngineID;
 
         static PredictionSettings fromIce(const armem::prediction::data::PredictionSettings& ice);
         armem::prediction::data::PredictionSettings toIce() const;
@@ -38,7 +47,7 @@ namespace armarx::armem::client
 
     struct PredictionRequest
     {
-        armem::MemoryID memoryID;
+        armem::MemoryID snapshotID;
         PredictionSettings predictionSettings;
 
         static PredictionRequest fromIce(const armem::prediction::data::PredictionRequest& ice);
@@ -48,14 +57,20 @@ namespace armarx::armem::client
     struct PredictionResult
     {
         bool success;
-        std::string errorMessage;
+        std::stringstream errorMessage;
 
+        armem::MemoryID snapshotID;
         aron::data::DictPtr prediction;
 
         static PredictionResult fromIce(const armem::prediction::data::PredictionResult& ice);
         armem::prediction::data::PredictionResult toIce() const;
     };
 
+    void toIce(armem::prediction::data::PredictionEngine& ice,
+               const PredictionEngine& engine);
+    void fromIce(const armem::prediction::data::PredictionEngine& ice,
+                 PredictionEngine& engine);
+
     void toIce(armem::prediction::data::PredictionSettings& ice,
                const PredictionSettings& settings);
     void fromIce(const armem::prediction::data::PredictionSettings& ice,
diff --git a/source/RobotAPI/libraries/armem/client/Reader.cpp b/source/RobotAPI/libraries/armem/client/Reader.cpp
index 0cd573bd4ccd95282cbf6cb63dced41f1d62a153..52be34eb42c8f5c54f2138731690a5f43728d6f8 100644
--- a/source/RobotAPI/libraries/armem/client/Reader.cpp
+++ b/source/RobotAPI/libraries/armem/client/Reader.cpp
@@ -3,11 +3,11 @@
 #include <sstream>
 
 #include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/ice_conversions/ice_conversions_templates.h>
 
 #include <RobotAPI/libraries/armem/aron/MemoryLink.aron.generated.h>
 #include <RobotAPI/libraries/armem/core/MemoryID_operators.h>
 #include <RobotAPI/libraries/armem/core/aron_conversions.h>
-#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/util/util.h>
 #include <RobotAPI/libraries/aron/common/util/object_finders.h>
@@ -37,30 +37,22 @@ namespace armarx::armem::client
     armem::query::data::Result
     Reader::query(const armem::query::data::Input& input) const
     {
-        auto makeErrorMsg = [](auto e)
+        armem::query::data::Result result;
+        if (!readingPrx)
         {
-            std::stringstream ss;
-            ss << "Memory query failed.\nReason: " << e.what();
-            return ss.str();
-        };
+            throw error::ProxyNotSet("ReadingMemoryInterfacePrx",
+                                     "Reading interface proxy must be set to perform a query.");
+        }
 
-        armem::query::data::Result result;
-        ARMARX_CHECK_NOT_NULL(readingPrx);
         try
         {
             result = readingPrx->query(input);
         }
-        catch (const Ice::ConnectionRefusedException& e)
-        {
-            result.errorMessage = makeErrorMsg(e);
-        }
-        catch (const Ice::ConnectionLostException& e)
-        {
-            result.errorMessage = makeErrorMsg(e);
-        }
-        catch (const Ice::NotRegisteredException& e)
+        catch (const Ice::LocalException& e)
         {
-            result.errorMessage = makeErrorMsg(e);
+            std::stringstream sstream;
+            sstream << "Memory query failed.\nReason: " << e.what();
+            result.errorMessage = sstream.str();
         }
         return result;
     }
@@ -99,15 +91,13 @@ namespace armarx::armem::client
             armem::client::MemoryNameSystem& mns,
             int recursionDepth) const
     {
-        auto makeErrorMsg = [](auto error)
+        if (!readingPrx)
         {
-            std::stringstream sstream;
-            sstream << "Memory query failed.\nReason: " << error.what();
-            return sstream.str();
-        };
+            throw error::ProxyNotSet("ReadingMemoryInterfacePrx",
+                                     "Reading interface proxy must be set to perform a query.");
+        }
 
         armem::query::data::Result result;
-        ARMARX_CHECK_NOT_NULL(readingPrx);
         try
         {
             result = readingPrx->query(input);
@@ -117,17 +107,11 @@ namespace armarx::armem::client
                 { resolveMemoryLinks(instance, bObj.memory, mns, recursionDepth); });
             result = bObj.toIce();
         }
-        catch (const Ice::ConnectionRefusedException& e)
-        {
-            result.errorMessage = makeErrorMsg(e);
-        }
-        catch (const Ice::ConnectionLostException& e)
-        {
-            result.errorMessage = makeErrorMsg(e);
-        }
-        catch (const Ice::NotRegisteredException& e)
+        catch (const Ice::LocalException& e)
         {
-            result.errorMessage = makeErrorMsg(e);
+            std::stringstream sstream;
+            sstream << "Memory query failed.\nReason: " << e.what();
+            result.errorMessage = sstream.str();
         }
         catch (const exceptions::local::ExpressionException& e)
         {
@@ -454,7 +438,12 @@ namespace armarx::armem::client
     std::vector<PredictionResult>
     Reader::predict(const std::vector<PredictionRequest>& requests) const
     {
-        ARMARX_CHECK_NOT_NULL(predictionPrx);
+        if (!predictionPrx)
+        {
+            throw error::ProxyNotSet(
+                "PredictingMemoryInterfacePrx",
+                "Prediction interface proxy must be set to request a prediction.");
+        }
 
         armem::prediction::data::PredictionRequestSeq iceRequests;
         for (const auto& request : requests)
@@ -490,12 +479,17 @@ namespace armarx::armem::client
         return boResults;
     }
 
-    std::vector<std::string>
+    std::vector<PredictionEngine>
     Reader::getAvailablePredictionEngines() const
     {
-        ARMARX_CHECK_NOT_NULL(predictionPrx);
+        if (!predictionPrx)
+        {
+            throw error::ProxyNotSet(
+                "PredictingMemoryInterfacePrx",
+                "Prediction interface proxy must be set to request a prediction.");
+        }
 
-        std::vector<std::string> engines;
+        std::vector<armem::prediction::data::PredictionEngine> engines;
         try
         {
             engines = predictionPrx->getAvailableEngines();
@@ -505,6 +499,13 @@ namespace armarx::armem::client
             // Just leave engines empty in this case.
         }
 
-        return engines;
+        std::vector<PredictionEngine> boEngines;
+        boEngines.reserve(engines.size());
+        for (const auto& engine : engines)
+        {
+            boEngines.push_back(armarx::fromIce<PredictionEngine>(engine));
+        }
+
+        return boEngines;
     }
 } // namespace armarx::armem::client
diff --git a/source/RobotAPI/libraries/armem/client/Reader.h b/source/RobotAPI/libraries/armem/client/Reader.h
index 2e5825a5e57491058c330ac891729bd7c1de0bb8..beb0e53f5ff25078cb881d4477c19c5cd291fe1a 100644
--- a/source/RobotAPI/libraries/armem/client/Reader.h
+++ b/source/RobotAPI/libraries/armem/client/Reader.h
@@ -185,7 +185,7 @@ namespace armarx::armem::client
          *
          * @return the vector of supported prediction engines
          */
-        std::vector<std::string> getAvailablePredictionEngines() const;
+        std::vector<PredictionEngine> getAvailablePredictionEngines() const;
 
         inline operator bool() const
         {
diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
index ac8be17b51fd8f67d90de93c77513d15b6ff8320..87b687447b7277cbd3861d7c29e3df566e3e26b3 100644
--- a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
+++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
@@ -220,4 +220,21 @@ namespace armarx::armem::error
         return ss.str();
     }
 
+    ProxyNotSet::ProxyNotSet(const std::string& proxyName, const std::string& message) :
+        ArMemError(makeMsg(proxyName, message))
+    {
+    }
+
+    std::string
+    ProxyNotSet::makeMsg(const std::string& proxyName, const std::string& message)
+    {
+        std::stringstream sstream;
+        sstream << "Proxy \"" << proxyName << "\" not set.";
+        if (!message.empty())
+        {
+            sstream << "\n" << message;
+        }
+        return sstream.str();
+    }
+
 } // namespace armarx::armem::error
diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.h b/source/RobotAPI/libraries/armem/core/error/ArMemError.h
index 5678ee1a9a8e452309f2127fa41f519858ee233c..6f5be02a243e9e953d56b67f5f1726be214b2745 100644
--- a/source/RobotAPI/libraries/armem/core/error/ArMemError.h
+++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.h
@@ -203,5 +203,15 @@ namespace armarx::armem::error
 
     };
 
-}
+    /**
+     * @brief Indicates that a proxy required for an operation wasn't usable.
+     */
+    class ProxyNotSet : public ArMemError
+    {
+    public:
+        ProxyNotSet(const std::string& proxyName, const std::string& message = "");
+
+        static std::string makeMsg(const std::string& proxyName, const std::string& message = "");
+    };
 
+} // namespace armarx::armem::error
diff --git a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp
index 45b08dfd35c50a75b1579f58af02ecb0855d3a83..115e38311ae09d9d5e1362bf362b1207a76173a8 100644
--- a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp
+++ b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp
@@ -1,6 +1,7 @@
 #include "ReadWritePluginUser.h"
 #include "Plugin.h"
 
+#include <RobotAPI/libraries/armem/client/Prediction.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 
@@ -124,11 +125,11 @@ namespace armarx::armem::server::plugins
         armem::prediction::data::PredictionResultSeq result;
         for (auto request : requests)
         {
-            armem::prediction::data::PredictionResult singleResult;
+            armem::client::PredictionResult singleResult;
             singleResult.success = false;
-            singleResult.errorMessage = "This memory does not implement predictions.";
+            singleResult.errorMessage << "This memory does not implement predictions.";
             singleResult.prediction = nullptr;
-            result.push_back(singleResult);
+            result.push_back(singleResult.toIce());
         }
         return result;
     }