diff --git a/lifx-lan.cabal b/lifx-lan.cabal
--- a/lifx-lan.cabal
+++ b/lifx-lan.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               lifx-lan
-version:            0.8.3
+version:            0.8.4
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             George Thomas
@@ -27,7 +27,7 @@
     ghc-options:
         -Wall
     build-depends:
-        base ^>= {4.16, 4.17, 4.18, 4.19},
+        base ^>= {4.16, 4.17, 4.18, 4.19, 4.20, 4.21},
         ansi-terminal ^>= {0.11.1, 1.0, 1.1},
         binary ^>= 0.8.8,
         bytestring ^>= {0.10.8, 0.11, 0.12},
diff --git a/src/Lifx/Lan/Mock/Terminal.hs b/src/Lifx/Lan/Mock/Terminal.hs
--- a/src/Lifx/Lan/Mock/Terminal.hs
+++ b/src/Lifx/Lan/Mock/Terminal.hs
@@ -95,7 +95,7 @@
     lifxThrow = Mock . throwError
     liftProductLookupError = MockProductLookupError
 
-    sendMessage d m = do
+    sendMessage d (m :: Message r) = do
         s <- lookupDevice d
         r <- Mock case m of
             GetService -> whenProvided s.service
@@ -119,6 +119,7 @@
         pure r
       where
         lookupDevice = maybe (lifxThrow $ MockNoSuchDevice d) pure <=< Mock . gets . Map.lookup
+        whenProvided :: Maybe r -> StateT (Map Device MockState) (ReaderT [Device] (ExceptT MockError IO)) r
         whenProvided = maybe (throwError MockDataNotProvided) pure
         convertPower = fromIntegral . fromEnum
         mkSGR s = [SetRGBColor Background . uncurryRGB sRGB $ hsbkToRgb s.hsbk | s.power /= 0]
