diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,14 @@
 
 ## Unreleased
 
+## 0.2.0.1 - 2026-03-29
+
+### Fixed
+
+- Fixed a bug where an exception thrown by the `onRemove` callback in the broom
+  sweep loop would take down the background sweep thread. Exceptions from
+  `onRemove` are now caught and silently discarded.
+
 ## 0.2.0.0 - 2026-03-29
 
 ### Changed
diff --git a/shared-resource-cache.cabal b/shared-resource-cache.cabal
--- a/shared-resource-cache.cabal
+++ b/shared-resource-cache.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           shared-resource-cache
-version:        0.2.0.0
+version:        0.2.0.1
 synopsis:       A thread-safe cache for sharing resources across threads with automatic expiry
 description:    A cache designed for guaranteeing that different threads can share the same reference to a resource. For example, it allows threads to communicate via a shared
                 <<https://hackage.haskell.org/package/stm-2.5.3.1/docs/Control-Concurrent-STM-TChan.html TChan broadcast channel>>. 
diff --git a/src/Data/SharedResourceCache.hs b/src/Data/SharedResourceCache.hs
--- a/src/Data/SharedResourceCache.hs
+++ b/src/Data/SharedResourceCache.hs
@@ -37,7 +37,7 @@
 makeGlobalSharedResourceCache
  :: Hashable key
  => (key -> IO (Either err value)) -- ^ The action to load the given resource by ID. If the 'Either' result is a 'Left' or the IO action throws, the result is not stored in the cache
- -> Maybe (value -> IO ()) -- ^ An action to be executed when the item is removed from the cache
+ -> Maybe (value -> IO ()) -- ^ An action to be executed when the item is removed from the cache. If this action throws an exception it is silently ignored.
  -> CacheExpiryConfig -- ^ The configuration for when the cache item should be marked as expired and be eligible for removal from the cache
  -> IO (SharedResourceCache key value err)
 makeGlobalSharedResourceCache loadResourceOp onRemoval cacheExpiryConfig@(CacheExpiryConfig sweepIntervalSeconds _) = do
diff --git a/src/Data/SharedResourceCache/Internal/Broom.hs b/src/Data/SharedResourceCache/Internal/Broom.hs
--- a/src/Data/SharedResourceCache/Internal/Broom.hs
+++ b/src/Data/SharedResourceCache/Internal/Broom.hs
@@ -7,6 +7,7 @@
     import Control.Monad (forever, when)
     import Control.Monad.STM (atomically)
     import Data.SharedResourceCache.Internal.CacheItem (numberOfSharers, CacheItem (cacheItem))
+    import Control.Exception (SomeException, catch)
     import Control.Concurrent (threadDelay)
     import ListT (traverse_)
     import Data.Time (addUTCTime, getCurrentTime)
@@ -25,7 +26,7 @@
         when (now >= cacheExpiryTime) $ do
             removed <- atomically $ removeIfNoSharers cache cleanUpMap resourceId
             case (removed, onRemove) of
-                (Just removedItem, Just onRemovalFunction) -> onRemovalFunction removedItem
+                (Just removedItem, Just onRemovalFunction) -> catch (onRemovalFunction removedItem) (\(_ :: SomeException) -> return ())
                 _ -> return ()
         where
             removeIfNoSharers :: M.Map key (CacheEntry value) -> M.Map key UTCTime -> key -> STM (Maybe value)
