diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+# effectful-2.5.0.0 (2024-10-23)
+* Add `plusEff` (specialized version of `<|>`) to `Effectful.NonDet` and make
+  `emptyEff` and `sumEff` generate better call stacks.
+* Explicitly define `setByteArray#` and `setOffAddr#` in the `Prim` instance of
+  `Ref` for `primitive` < 0.9.0.0.
+* **Bugfixes**:
+  - `OnEmptyRollback` strategy of the `NonDet` effect is no longer broken.
+* **Breaking changes**:
+  - Remove `restoreEnv` function from `Effectful.Dispatch.Static.Primitive`
+    since it was broken.
+  - Base `Effectful.Exception` on `Control.Exception` instead of the
+    `safe-exceptions` library for consistency with provided `MonadThrow` and
+    `MonadCatch` instances.
+
 # effectful-2.4.0.0 (2024-10-08)
 * Add utility functions for handling effects that take the effect handler as the
   last parameter to `Effectful.Dispatch.Dynamic`.
diff --git a/effectful.cabal b/effectful.cabal
--- a/effectful.cabal
+++ b/effectful.cabal
@@ -1,7 +1,7 @@
 cabal-version:      3.0
 build-type:         Simple
 name:               effectful
-version:            2.4.0.0
+version:            2.5.0.0
 license:            BSD-3-Clause
 license-file:       LICENSE
 category:           Control
@@ -74,7 +74,7 @@
                     , async               >= 2.2.2
                     , bytestring          >= 0.10
                     , directory           >= 1.3.2
-                    , effectful-core      >= 2.4.0.0   && < 2.4.1.0
+                    , effectful-core      >= 2.5.0.0   && < 2.5.1.0
                     , process             >= 1.6.9
                     , strict-mutable-base >= 1.1.0.0
                     , time                >= 1.9.2
diff --git a/tests/EnvTests.hs b/tests/EnvTests.hs
--- a/tests/EnvTests.hs
+++ b/tests/EnvTests.hs
@@ -104,8 +104,6 @@
 test_noUnsafeCoerce = do
   r1 <- try @ErrorCall . evaluate $ unsafeCoerce1 @Int 'a'
   assertBool "unsafeCoerce1" (isLeft r1)
-  r2 <- try @ErrorCall . evaluate $ unsafeCoerce2 @Int 'a'
-  assertBool "unsafeCoerce2" (isLeft r2)
 
 unsafeCoerce1 :: forall b a. a -> b
 unsafeCoerce1 a = runPureEff $ do
@@ -115,26 +113,6 @@
   oops <- runReader @(Box b) (Box undefined) $ do
     raiseWith SeqUnlift $ \unlift -> do
       pure . unlift $ ask @(Box b)
-  -- Put Reader (Box a) where the Reader (Box b) was before and attempt to
-  -- retrieve 'a' coerced to 'b'. It should fail because 'getLocation' in
-  -- 'Effectful.Internal.Env' checks that version of the reference is the same
-  -- as version of the effect.
-  Box b <- runReader (Box a) $ raise oops
-  pure b
-
-unsafeCoerce2 :: forall b a. a -> b
-unsafeCoerce2 a = runPureEff $ do
-  backupEs <- unsafeEff cloneEnv
-  -- 'oops' gains access to the effect stack with Reader (Box b) via the
-  -- unlifting function that escaped its scope. The problem here is that this
-  -- effect is no longer in scope.
-  oops <- runReader @(Box b) (Box undefined) $ do
-    raiseWith SeqUnlift $ \unlift -> do
-      pure . unlift $ ask @(Box b)
-  -- If restoreEnv messes up versioning (i.e. restores the version counter from
-  -- before the above Reader was used), below code will succeed because the
-  -- Reader (Box a) will have the same version as Reader (Box b).
-  unsafeEff $ \es -> restoreEnv es backupEs
   -- Put Reader (Box a) where the Reader (Box b) was before and attempt to
   -- retrieve 'a' coerced to 'b'. It should fail because 'getLocation' in
   -- 'Effectful.Internal.Env' checks that version of the reference is the same
diff --git a/tests/StateTests.hs b/tests/StateTests.hs
--- a/tests/StateTests.hs
+++ b/tests/StateTests.hs
@@ -51,7 +51,7 @@
   U.assertEqual "correct a" "hi"    a
   U.assertEqual "correct b" "hi!!!" b
   where
-    getEffectReps = unsafeEff $ \es -> stEffects <$> readIORef' (envStorage es)
+    getEffectReps = unsafeEff $ \es -> sdEffects . stData <$> readIORef' (envStorage es)
 
 test_deepStack :: Assertion
 test_deepStack = runEff $ do
