diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Revision history for quickcheck-lockstep
 
+## 0.5.0 -- 2024-03-25
+
+* BREAKING: Update `quickcheck-dynamic` dependency to `>=3.4.1`. The main change
+  is that `quickcheck-dynamic`'s `StateModel` class now has an associated type
+  `Error`, the use of which is optional. However, as a result, some functions in
+  `quickcheck-lockstep` change type signatures: the default `monitoring`
+  function, `runActions`, and `runActionsBracket`.
+
 ## 0.4.1 -- 2024-03-20
 
 * PATCH: fix compilation failures when using `mtl ^>=2.3`
diff --git a/quickcheck-lockstep.cabal b/quickcheck-lockstep.cabal
--- a/quickcheck-lockstep.cabal
+++ b/quickcheck-lockstep.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               quickcheck-lockstep
-version:            0.4.1
+version:            0.5.0
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             Edsko de Vries
@@ -65,7 +65,7 @@
     , mtl                >= 2.2    && < 2.4
     , containers         >= 0.6    && < 0.7
     , QuickCheck         >= 2.14   && < 2.15
-    , quickcheck-dynamic >= 3.3.1  && < 3.4
+    , quickcheck-dynamic >= 3.4.1  && < 3.5
   hs-source-dirs:
       src
 
diff --git a/src/Test/QuickCheck/StateModel/Lockstep/Defaults.hs b/src/Test/QuickCheck/StateModel/Lockstep/Defaults.hs
--- a/src/Test/QuickCheck/StateModel/Lockstep/Defaults.hs
+++ b/src/Test/QuickCheck/StateModel/Lockstep/Defaults.hs
@@ -26,7 +26,7 @@
 import Test.QuickCheck (Gen, Property)
 import Test.QuickCheck qualified as QC
 import Test.QuickCheck.StateModel ( Var, Any(..), LookUp, Realized, PostconditionM
-                                  , Action, monitorPost)
+                                  , Action, monitorPost, StateModel (Error))
 import Test.QuickCheck.StateModel.Variables (VarContext, HasVariables (..))
 
 import Test.QuickCheck.StateModel.Lockstep.API
@@ -111,7 +111,7 @@
   -> (Lockstep state, Lockstep state)
   -> LockstepAction state a
   -> LookUp m
-  -> Realized m a
+  -> Either (Error (Lockstep state)) (Realized m a)
   -> Property -> Property
 monitoring _p (before, after) action _lookUp _realResp =
       QC.counterexample ("State: " ++ show after)
diff --git a/src/Test/QuickCheck/StateModel/Lockstep/Run.hs b/src/Test/QuickCheck/StateModel/Lockstep/Run.hs
--- a/src/Test/QuickCheck/StateModel/Lockstep/Run.hs
+++ b/src/Test/QuickCheck/StateModel/Lockstep/Run.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE TypeOperators #-}
+
 -- | Run lockstep tests
 --
 -- Intended for qualified import.
@@ -91,10 +93,13 @@
 -------------------------------------------------------------------------------}
 
 runActions ::
-     RunLockstep state IO
+     ( RunLockstep state IO
+     , e ~ Error (Lockstep state)
+     , forall a. IsPerformResult e a
+     )
   => Proxy state
   -> Actions (Lockstep state) -> Property
-runActions _ actions = monadicIO $ void $ StateModel.runActions actions
+runActions _ actions = monadicIO $ void $ StateModel.runActions  actions
 
 -- | Convenience runner with support for state initialization
 --
@@ -105,7 +110,10 @@
 -- @'ReaderT' r 'IO'@. In this case, using @'runReaderT'@ as the runner argument
 -- is a reasonable choice.
 runActionsBracket ::
-     RunLockstep state m
+     ( RunLockstep state m
+     , e ~ Error (Lockstep state)
+     , forall a. IsPerformResult e a
+     )
   => Proxy state
   -> IO st         -- ^ Initialisation
   -> (st -> IO ()) -- ^ Cleanup
