diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
 
 `hslua-module-system` uses [PVP Versioning][].
 
+## hslua-module-system-1.1.2
+
+Released 2024-05-28.
+
+-   Fixed error handling in `with_wd`: exceptions when changing
+    directories are now properly converted to Lua errors.
+
 ## hslua-module-system-1.1.1
 
 Released 2024-01-18.
diff --git a/hslua-module-system.cabal b/hslua-module-system.cabal
--- a/hslua-module-system.cabal
+++ b/hslua-module-system.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                hslua-module-system
-version:             1.1.1
+version:             1.1.2
 synopsis:            Lua module wrapper around Haskell's System module.
 
 description:         Provides access to system information and
@@ -26,8 +26,9 @@
                    , GHC == 9.0.2
                    , GHC == 9.2.8
                    , GHC == 9.4.8
-                   , GHC == 9.6.3
-                   , GHC == 9.8.1
+                   , GHC == 9.6.5
+                   , GHC == 9.8.2
+                   , GHC == 9.10.1
 
 source-repository head
   type:              git
diff --git a/src/HsLua/Module/System.hs b/src/HsLua/Module/System.hs
--- a/src/HsLua/Module/System.hs
+++ b/src/HsLua/Module/System.hs
@@ -47,7 +47,6 @@
 import HsLua.Module.SystemUtils
 
 import qualified Data.Text as T
-import qualified HsLua.Core as Lua
 import qualified System.CPUTime as CPUTime
 import qualified System.Directory as Directory
 import qualified System.Environment as Env
@@ -291,10 +290,10 @@
 with_wd :: LuaError e => DocumentedFunction e
 with_wd = defun "with_wd"
   ### (\fp callback ->
-        bracket (Lua.liftIO Directory.getCurrentDirectory)
-                (Lua.liftIO . Directory.setCurrentDirectory)
-        (\_ -> do
-              Lua.liftIO (Directory.setCurrentDirectory fp)
+        bracket (ioToLua Directory.getCurrentDirectory)
+                (ioToLua . Directory.setCurrentDirectory)
+           (\_ -> do
+              ioToLua (Directory.setCurrentDirectory fp)
               callback `invokeWithFilePath` fp))
   <#> filepathParam "directory"
         "Directory in which the given `callback` should be executed"
@@ -312,7 +311,7 @@
 with_env :: LuaError e => DocumentedFunction e
 with_env = defun "with_env"
   ### (\environment callback ->
-        bracket (Lua.liftIO Env.getEnvironment)
+        bracket (ioToLua Env.getEnvironment)
                 setEnvironment
                 (\_ -> setEnvironment environment *> invoke callback))
   <#> parameter (peekKeyValuePairs peekString peekString) "table"
@@ -330,7 +329,7 @@
      , "action."
      ]
  where
-  setEnvironment newEnv = Lua.liftIO $ do
+  setEnvironment newEnv = ioToLua $ do
     -- Crude, but fast enough: delete all entries in new environment,
     -- then restore old environment one-by-one.
     curEnv <- Env.getEnvironment
diff --git a/test/test-system.lua b/test/test-system.lua
--- a/test/test-system.lua
+++ b/test/test-system.lua
@@ -216,5 +216,13 @@
       end)
       assert.are_same({a, b, c}, {'a', 'b', 'c'})
     end),
+    test('raises an error on nonexistent directory', function ()
+      assert.error_matches(
+        function ()
+          system.with_wd('does-not-exist', function () end)
+        end,
+        'does not exist'
+      )
+    end)
   },
 }
