diff --git a/Shelly.hs b/Shelly.hs
--- a/Shelly.hs
+++ b/Shelly.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable, OverloadedStrings,
-             MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, IncoherentInstances #-}
+             MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, TypeFamilies, IncoherentInstances #-}
 
 -- | A module for shell-like / perl-like programming in Haskell.
 -- Shelly's focus is entirely on ease of use for those coming from shell scripting.
@@ -159,17 +159,25 @@
 instance ShellCommand (ShIO Text) where
     cmdAll fp args = run fp args
 
--- note that ShIO () actually doesn't compile all the time!
-instance ShellCommand (ShIO a) where
-    cmdAll fp args = run_ fp args >>
-      return (error "No Way! Shelly did not see this coming. Please report this error.")
+instance (s ~ Text, Show s) => ShellCommand (ShIO s) where
+    cmdAll fp args = run fp args
 
+-- note that ShIO () actually doesn't work for its case (_<- cmd) when there is no type signature
+instance ShellCommand (ShIO ()) where
+    cmdAll fp args = run_ fp args >> liftIO (throwIO CmdError)
+
+data CmdError = CmdError deriving Typeable
+instance Show CmdError where
+  show (CmdError) = "Sorry! You are running up against some of the magic from using the variadic argument function 'cmd'. Please report this issue so we can fix it."
+
+instance Exception CmdError
+
 instance (ShellArg arg, ShellCommand result) => ShellCommand (arg -> result) where
     cmdAll fp acc = \x -> cmdAll fp (acc ++ [toTextArg x])
 
 -- | variadic argument version of run.
--- The syntax is more convenient but it also allows the use of a FilePath as an argument.
--- An argument can be a Text or a FilePath.
+-- The syntax is more convenient but it also allows the use of a FilePath as a command argument.
+-- So an argument can be a Text or a FilePath.
 -- a FilePath is converted to Text with 'toTextIgnore'.
 -- You will need to add the following to your module:
 --
@@ -288,6 +296,7 @@
 gets :: (State -> a) -> ShIO a
 gets f = f <$> get
 
+-- FIXME: find the full path to the exe from PATH
 runInteractiveProcess' :: FilePath -> [Text] -> ShIO (Handle, Handle, Handle, ProcessHandle)
 runInteractiveProcess' exe args = do
   st <- get
@@ -427,7 +436,9 @@
 
 -- | a print lifted into ShIO
 inspect :: (Show s) => s -> ShIO ()
-inspect = trace . LT.pack . show >=> liftIO . print
+inspect x = do
+  (trace . LT.pack . show) x
+  liftIO $ print x
 
 -- | Create a new directory (fails if the directory exists).
 mkdir :: FilePath -> ShIO ()
@@ -443,8 +454,9 @@
   liftIO $ createTree fp
 
 -- | Get a full path to an executable on @PATH@, if exists. FIXME does not
--- respect setenv'd environment and uses @PATH@ inherited from the process
+-- respect setenv'd environment and uses @findExecutable@ which uses the @PATH@ inherited from the process
 -- environment.
+-- FIXME: findExecutable does not maintain a hash of existing commands and does a ton of file stats
 which :: FilePath -> ShIO (Maybe FilePath)
 which fp = do
   (trace . mappend "which " . toTextIgnore) fp
@@ -516,7 +528,7 @@
    in modify $ \x -> x { sEnvironment = wibble $ sEnvironment x }
 
 -- | add the filepath onto the PATH env variable
--- FIXME: see comments for "which"
+-- FIXME: only effects the PATH once the process is ran, as per comments in 'which'
 appendToPath :: FilePath -> ShIO ()
 appendToPath filepath = do
   tp <- toTextWarn filepath
@@ -552,7 +564,7 @@
 print_stdout :: Bool -> ShIO a -> ShIO a
 print_stdout shouldPrint a = sub $ modify (\x -> x { sPrintStdout = shouldPrint }) >> a
 
--- | Create a 'BgJobManager' which has a 'limit' on the max number of background tasks.
+-- | Create a 'BgJobManager' that has a 'limit' on the max number of background tasks.
 -- an invocation of jobs is independent of any others, and not tied to the ShIO monad in any way.
 -- This blocks the execution of the program until all 'background' jobs are finished.
 jobs :: Int -> (BgJobManager -> ShIO a) -> ShIO a
diff --git a/shelly.cabal b/shelly.cabal
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -1,6 +1,6 @@
 Name:       shelly
 
-Version:     0.9.2
+Version:     0.9.3
 Synopsis:    shell-like (systems) programming in Haskell
 
 Description: Shelly provides a single module for convenient
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -1,5 +1,6 @@
 {-# Language OverloadedStrings #-}
 {-# Language ExtendedDefaultRules #-}
+{-# Language ScopedTypeVariables #-}
 {-# OPTIONS_GHC -fno-warn-type-defaults #-}
 
 import Shelly
@@ -8,19 +9,30 @@
 
 main :: IO ()
 main =
-  shelly $ do
+  shelly $
+    -- verbosely $
+    do
     jobs 2 $ \job -> do
-      background job $ cmd "sleep" "2"
-      echo "yawn"
-      background job $ cmd "sleep" "2"
-      echo "tired"
-      background job $ cmd "sleep" "2"
-      echo "zzzz"
+      _<- background job $ cmd "sleep" "2"
+      echo "immediate"
+      _<- background job $ cmd "sleep" "2"
+      echo "immediate2"
+      _<- background job $ cmd "sleep" "2"
+      echo "blocked by background "
  
+    echo "blocked by jobs"
+
     setStdin "in"
-    echo "echo"
-    setStdin "catted"
+    setStdin "override stdin"
     run_ "cat" ["-"]
-    res <- cmd "echo" "foo"
+
+    recho <- cmd "echo" "cmd"
     _<-cmd "echo" "bar" "baz"
-    echo res
+    echo recho
+
+    (res :: Text) <- cmd "pwd"
+    liftIO $ putStrLn $ show res
+    inspect res
+
+    inspect =<< (cmd "echo" "compose" :: ShIO Text)
+    inspect =<< (cmd "pwd")
