diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,12 @@
 # Changelog for `annotated-exception`
 
+## 0.3.0.4
+
+- [#37](https://github.com/parsonsmatt/annotated-exception/pull/37)
+    - Removed a trailing newline from the `AnnotatedException`
+      `displayException` implementation (this was a regression introduced in
+      0.3.0.3).
+
 ## 0.3.0.3
 
 - [#36](https://github.com/parsonsmatt/annotated-exception/pull/36)
diff --git a/annotated-exception.cabal b/annotated-exception.cabal
--- a/annotated-exception.cabal
+++ b/annotated-exception.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           annotated-exception
-version:        0.3.0.3
+version:        0.3.0.4
 synopsis:       Exceptions, with checkpoints and context.
 description:    Please see the README on Github at <https://github.com/parsonsmatt/annotated-exception#readme>
 category:       Control
diff --git a/src/Control/Exception/Annotated.hs b/src/Control/Exception/Annotated.hs
--- a/src/Control/Exception/Annotated.hs
+++ b/src/Control/Exception/Annotated.hs
@@ -63,6 +63,7 @@
        (Exception, Handler(..), MonadCatch, MonadThrow, SomeException(..))
 import qualified Control.Exception.Safe as Safe
 import Data.Annotation
+import Data.List (intersperse)
 import Data.Maybe
 import qualified Data.Set as Set
 import Data.Typeable
@@ -123,7 +124,7 @@
             Nothing
 
     displayException (AnnotatedException{..}) =
-        unlines $
+        concat $ intersperse "\n" $
             [ "! AnnotatedException !"
             , "Underlying exception type: " <> show exceptionType
             , ""
diff --git a/test/Control/Exception/AnnotatedSpec.hs b/test/Control/Exception/AnnotatedSpec.hs
--- a/test/Control/Exception/AnnotatedSpec.hs
+++ b/test/Control/Exception/AnnotatedSpec.hs
@@ -15,7 +15,7 @@
 import qualified Control.Exception.Safe as Safe
 import Data.Annotation
 import Data.AnnotationSpec ()
-import Data.List (dropWhileEnd)
+import Data.List (dropWhileEnd, intersperse)
 import Data.Maybe
 import Data.Typeable
 import GHC.Stack
@@ -44,9 +44,18 @@
 emptyAnnotation :: e -> AnnotatedException e
 emptyAnnotation = pure
 
+-- | GHC 9.10.1 introduced a regression that added an extra newline to the end
+-- of the `displayException` output for `SomeException`.
+--
+-- See: https://gitlab.haskell.org/ghc/ghc/-/issues/25052
 trimTrailingNewlines :: String -> String
 trimTrailingNewlines = dropWhileEnd (== '\n')
 
+-- | Join a list of lines with newlines.
+--
+-- Unlike `unlines`, this doesn't add a newline at the end of the string.
+joinLines = concat . intersperse "\n"
+
 spec :: Spec
 spec = do
     describe "toException" $ do
@@ -71,8 +80,8 @@
                 `shouldBe` trimTrailingNewlines (displayException (SomeException TestException))
 
         it "uses show and displayException if they're different" $ do
-            lines (displayException (AnnotatedException [] TestDisplayException))
-                `shouldBe`
+            displayException (AnnotatedException [] TestDisplayException)
+                `shouldBe` joinLines
                     [ "! AnnotatedException !"
                     , "Underlying exception type: TestDisplayException"
                     , ""
@@ -86,8 +95,8 @@
                     ]
 
         it "is reasonably nice to look at" $ do
-            lines (displayException (AnnotatedException [] TestException))
-                `shouldBe`
+            displayException (AnnotatedException [] TestException)
+                `shouldBe` joinLines
                     [ "! AnnotatedException !"
                     , "Underlying exception type: TestException"
                     , ""
@@ -97,8 +106,8 @@
                     ]
 
         it "is reasonably nice to look at" $ do
-            lines (displayException (AnnotatedException [Annotation @String "asdf"] TestException))
-                `shouldBe`
+            displayException (AnnotatedException [Annotation @String "asdf"] TestException)
+                `shouldBe` joinLines
                     [ "! AnnotatedException !"
                     , "Underlying exception type: TestException"
                     , ""
@@ -112,7 +121,7 @@
 
         it "shows underlying exception type" $ do
             Left exn <- try $ throwWithCallStack (AnnotatedException [Annotation @String "asdf"] TestException)
-            let resultLines =
+            let result = joinLines
                     [ "! AnnotatedException !"
                     , "Underlying exception type: TestException"
                     , ""
@@ -123,8 +132,8 @@
                     , ""
                     , "CallStack (from HasCallStack):"
                     ]
-            take (length resultLines) (lines (displayException (exn :: AnnotatedException TestException)))
-                `shouldBe` resultLines
+            take (length result) (displayException (exn :: AnnotatedException TestException))
+                `shouldBe` result
 
     describe "AnnotatedException can fromException a" $ do
         it "different type" $ do
