diff --git a/core-program.cabal b/core-program.cabal
--- a/core-program.cabal
+++ b/core-program.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           core-program
-version:        0.6.9.2
+version:        0.6.9.4
 synopsis:       Opinionated Haskell Interoperability
 description:    A library to help build command-line programs, both tools and
                 longer-running daemons.
@@ -27,7 +27,7 @@
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 8.10.7, GHC == 9.2.7
+    GHC == 8.10.7, GHC == 9.2.7, GHC == 9.4.5
 
 source-repository head
   type: git
diff --git a/lib/Core/Program/Arguments.hs b/lib/Core/Program/Arguments.hs
--- a/lib/Core/Program/Arguments.hs
+++ b/lib/Core/Program/Arguments.hs
@@ -935,7 +935,7 @@
         Nothing -> "COMMAND..."
 
     argumentsSummary :: [Options] -> Doc ann
-    argumentsSummary as = " " <> fillSep (fmap (\x -> "<" <> pretty x <> ">") (extractRequiredArguments as))
+    argumentsSummary as = " " <> fillSep (fmap (\x -> "<" <> pretty x <> ">") (reverse (extractRequiredArguments as)))
 
     argumentsHeading as = if length as > 0 then hardline <> "Required arguments:" <> hardline else emptyDoc
 
diff --git a/lib/Core/Program/Threads.hs b/lib/Core/Program/Threads.hs
--- a/lib/Core/Program/Threads.hs
+++ b/lib/Core/Program/Threads.hs
@@ -62,6 +62,7 @@
 import Control.Monad.Reader.Class (MonadReader (ask))
 import Core.Data.Structures
 import Core.Program.Context
+import Core.Program.Exceptions
 import Core.Program.Execute
 import Core.Program.Logging
 import Core.System.Base
@@ -479,19 +480,37 @@
         outcome <- liftIO $ do
             newEmptyMVar
 
-        _ <- forkThread $ do
-            !result1 <- one
-            liftIO $ do
-                putMVar outcome (Left result1)
+        t1 <- forkThread $ do
+            finally
+                ( do
+                    one
+                )
+                ( do
+                    liftIO $ do
+                        putMVar outcome (Left ())
+                )
 
-        _ <- forkThread $ do
-            !result2 <- two
-            liftIO $ do
-                putMVar outcome (Right result2)
+        t2 <- forkThread $ do
+            finally
+                ( do
+                    two
+                )
+                ( do
+                    liftIO $ do
+                        putMVar outcome (Right ())
+                )
 
-        liftIO $ do
+        result <- liftIO $ do
             readMVar outcome
 
+        case result of
+            Left _ -> do
+                result1 <- waitThread t1
+                pure (Left result1)
+            Right _ -> do
+                result2 <- waitThread t2
+                pure (Right result2)
+
 {- |
 Fork two threads and race them against each other. When one action completes
 the other will be cancelled with an exception. This is useful for enforcing
@@ -515,7 +534,7 @@
 linkThread _ = pure ()
 {-# DEPRECATED linkThread "Exceptions are bidirectional so linkThread no longer needed" #-}
 
-{-|
+{- |
 If a timeout is exceeded this exception will be thrown by 'timeoutThread'.
 
 @since 0.6.9
