diff --git a/emper/ContextManager.cpp b/emper/ContextManager.cpp
index 88a651c86856d27a0b36ecfb895d08e5cf7d06bf..7a15eb4b6002bea2e095ff0a0d963284b20bdc2e 100644
--- a/emper/ContextManager.cpp
+++ b/emper/ContextManager.cpp
@@ -64,5 +64,17 @@ void ContextManager::discardAndResume(Context* context) {
 			LOGD("Freeing context " << contextToFree);
 			putFreeContext(contextToFree);
 	});
+
+	// Since we are going to discard this context, it will never reach
+	// the end of its dispatch loop, and hence we need to ensure that
+	// the fiber is recycled.
+	const Fiber* currentFiber = Dispatcher::currentFiber;
+	if (currentFiber) {
+		Dispatcher::recycle(currentFiber);
+
+		// Set currentFiber to nullptr to avoid double frees here.
+		Dispatcher::currentFiber = nullptr;
+	}
+
 	contextToFree->discardAndResume(context);
 }
diff --git a/emper/ContextManager.hpp b/emper/ContextManager.hpp
index e39f5b32930c6732c314f1b2059a68ba3603e70c..35cbfc8757cf803e9182510516660300d7c266f2 100644
--- a/emper/ContextManager.hpp
+++ b/emper/ContextManager.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "Common.hpp"
+#include "Dispatcher.hpp"
 #include "WsClQueue.hpp"
 #include "Runtime.hpp"
 #include "Context.hpp"
@@ -17,6 +18,8 @@ private:
 
 	friend Context;
 
+	friend Dispatcher;
+
 public:
 	ContextManager(Runtime& runtime);
 
diff --git a/emper/Dispatcher.hpp b/emper/Dispatcher.hpp
index 16a6b8846e3b0bcf32d709caa4545b40da0b35a5..f7b8d11799419e11d03144dd67a2fd060761cbed 100644
--- a/emper/Dispatcher.hpp
+++ b/emper/Dispatcher.hpp
@@ -35,7 +35,7 @@ protected:
 		return fiber->doAtomicDecrRefCount();
 	}
 
-	inline void recycle(const Fiber* fiber) {
+	static inline void recycle(const Fiber* fiber) {
 		delete fiber;
 	}