diff --git a/data/pandoc.lua b/data/pandoc.lua
index fc83103e0..32e593c22 100644
--- a/data/pandoc.lua
+++ b/data/pandoc.lua
@@ -792,6 +792,8 @@ end
 
 --- Runs command with arguments, passing it some input, and returns the output.
 -- @treturn string Output of command.
+-- @raise A table containing the keys `command`, `error_code`, and `output` is
+-- thrown if the command exits with a non-zero error code.
 -- @usage
 -- local ec, output = pandoc.pipe("sed", {"-e","s/a/b/"}, "abc")
 function M.pipe (command, args, input)
@@ -806,9 +808,7 @@ function M.pipe (command, args, input)
         end
       }
     )
-    -- TODO: drop the wrapping call to `tostring` as soon as hslua supports
-    -- non-string error objects.
-    error(tostring(err))
+    error(err)
   end
   return output
 end
diff --git a/doc/lua-filters.md b/doc/lua-filters.md
index bdb56f9db..8c8268c20 100644
--- a/doc/lua-filters.md
+++ b/doc/lua-filters.md
@@ -1132,6 +1132,12 @@ Lua functions for pandoc scripts.
 
     -   Output of command.
 
+    Raises:
+
+    -   A table containing the keys `command`, `error_code`, and
+        `output` is thrown if the command exits with a non-zero
+        error code.
+
     Usage:
 
         local output = pandoc.pipe("sed", {"-e","s/a/b/"}, "abc")
diff --git a/src/Text/Pandoc/Lua.hs b/src/Text/Pandoc/Lua.hs
index 2e4204898..583d43a2e 100644
--- a/src/Text/Pandoc/Lua.hs
+++ b/src/Text/Pandoc/Lua.hs
@@ -196,9 +196,8 @@ runFilterFunction lf x = do
   push x
   z <- Lua.pcall 1 1 Nothing
   when (z /= OK) $ do
-    msg <- Lua.peek (-1) <* Lua.pop 1
-    let prefix = "Error while running filter function: "
-    Lua.throwLuaError $ prefix ++ msg
+    let addPrefix = ("Error while running filter function: " ++)
+    Lua.throwTopMessageAsError' addPrefix
 
 elementOrList :: FromLuaStack a => a -> Lua [a]
 elementOrList x = do