diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Revision history for railroad
 
+## 0.1.0.1 -- 2026-02-26
+
+* Fix that `Railroad.MonadError` is not exposed in the cabal file
+* Fix ambiguous occurrence of `(??~)` in `Railroad.MonadError` by hiding it in import.
+* Add tests for the MonadError version of the operators such that issues like the above will be caught 
+
 ## 0.1.0.0 -- 2026-02-25
 
 * First version. Released on an unsuspecting world.
diff --git a/railroad.cabal b/railroad.cabal
--- a/railroad.cabal
+++ b/railroad.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               railroad
-version:            0.1.0.0
+version:            0.1.0.1
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             Frederik Kallstrup Mastratisi
@@ -29,7 +29,7 @@
 library
     import:           stuff
     exposed-modules:  Railroad
-                      
+                      Railroad.MonadError
     hs-source-dirs:   src
     default-language: GHC2021
     
@@ -41,6 +41,7 @@
     hs-source-dirs:   test
     main-is:          Main.hs
     other-modules:    RailroadSpec
+                      Railroad.MonadErrorSpec
     build-depends:
                   base ^>=4.20.2.0,
                   hspec  >= 2.11.14 && < 2.12,
diff --git a/src/Railroad/MonadError.hs b/src/Railroad/MonadError.hs
new file mode 100644
--- /dev/null
+++ b/src/Railroad/MonadError.hs
@@ -0,0 +1,71 @@
+-- |
+-- Re-implementation of Railroad operators ('??', '?', '?>', etc.)
+-- using 'MonadError' / 'throwError' instead of the Effectful 'Error' effect.
+--
+-- Use this module in classic @mtl@ / @transformers@ / @ExceptT@ code.
+-- For Effectful prefer the versions from "Railroad".
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts    #-}
+
+module Railroad.MonadError
+  ( module Railroad          -- re-exports CErr, CRes, Bifurcate, CardinalityError, etc.
+  , collapse
+  , (??), (?), (?>), (??~), (?~), (?+), (?!), (?∅)
+  ) where
+
+import           Railroad             hiding (collapse, (?!), (?), (?+), (?>),
+                                       (??), (??~), (?~), (?∅))
+
+import           Control.Monad.Except (MonadError (..))
+import           Data.Foldable        (toList)
+
+-- | Collapses a structure into its inner type or a `MonadError` error.
+collapse :: (MonadError e m, Bifurcate f)
+         => (CErr f -> e) -> f -> m (CRes f)
+collapse toErr = either (throwError . toErr) pure . bifurcate
+
+(??) :: forall a m e. (MonadError e m, Bifurcate a)
+     => m a -> (CErr a -> e) -> m (CRes a)
+action ?? toErr = action >>= collapse toErr
+
+(?) :: forall m e a. (MonadError e m, Bifurcate a)
+    => m a -> e -> m (CRes a)
+action ? err = action ?? const err
+
+(?>) :: forall m e a. (MonadError e m)
+     => m a -> (a -> Bool) -> (a -> e) -> m a
+(?>) action predicate toErr = do
+  val <- action
+  if predicate val then pure val else throwError $ toErr val
+
+-- | Collapses a structure and recovers to a value dependent on the error
+(??~) :: forall m a. (Bifurcate a, Monad m) => m a -> (CErr a -> CRes a) -> m (CRes a)
+action ??~ defaultFunc = action >>= either (pure . defaultFunc) pure . bifurcate
+
+-- | Collapses a structure, and recovers to a constant default value in the error case
+(?~) :: forall m a. (Bifurcate a, Monad m) => m a -> CRes a -> m (CRes a)
+action ?~ defaultVal = action ??~ (const defaultVal)
+
+(?+) :: forall m e t a. (MonadError e m, Foldable t)
+     => m (t a) -> e -> m (t a)
+(?+) action err = do
+  xs <- action
+  if null xs then throwError err else pure xs
+
+(?!) :: forall m e t a. (MonadError e m, Foldable t)
+     => m (t a) -> (CardinalityError (t a) -> e) -> m a
+(?!) action toErr = do
+  xs <- action
+  case toList xs of
+    []  -> throwError $ toErr IsEmpty
+    [x] -> pure x
+    _   -> throwError $ toErr $ TooMany xs
+
+(?∅) :: forall m e t a. (MonadError e m, Foldable t)
+     => m (t a) -> (t a -> e) -> m ()
+(?∅) action toErr = do
+  xs <- action
+  if null xs then pure () else throwError (toErr xs)
+
+infixl 0 ??, ?, ?~, ?!, ?+, ?∅
+infixl 1 ?>
diff --git a/test/Railroad/MonadErrorSpec.hs b/test/Railroad/MonadErrorSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Railroad/MonadErrorSpec.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE TypeApplications #-}
+
+module Railroad.MonadErrorSpec where
+
+import           Control.Monad.Except
+import           Data.Functor.Identity
+import           Data.Validation
+import           Railroad.MonadError
+import           Test.Hspec
+
+-- Helper to run MonadError computations in pure Either
+runMonadError :: ExceptT String Identity a -> Either String a
+runMonadError = runIdentity . runExceptT
+
+spec :: Spec
+spec = do
+  describe "MonadError version of Operators" $ do
+    describe "Basic Operators (? and ??)" $ do
+      it "unwraps success values with (?)" $ do
+        runMonadError (pure (Just 10 :: Maybe Int) ? "missing") `shouldBe` Right 10
+      it "throws constant error on failure with (?)" $ do
+        runMonadError (pure (Nothing :: Maybe ()) ? "missing") `shouldBe` Left "missing"
+      it "maps internal errors with (??)" $ do
+        let action = pure (Left "original" :: Either String String)
+        runMonadError (action ?? reverse) `shouldBe` Left "lanigiro"
+
+    describe "Predicate Operator (?>)" $ do
+      it "passes when predicate is met" $ do
+        runMonadError (pure 10 ?> (> 5) $ const "too small") `shouldBe` Right 10
+      it "fails when predicate is not met" $ do
+        runMonadError (pure 4 ?> (> 5) $ const "too small") `shouldBe` Left "too small"
+
+    describe "Recovery Operators (?~ and ??~)" $ do
+      it "recovers to a constant value with (?~)" $ do
+        runMonadError (pure Nothing ?~ 0) `shouldBe` Right (0 :: Int)
+      it "recovers using a function with (??~)" $ do
+        runMonadError (pure (Left "err") ??~ length) `shouldBe` Right 3
+
+    describe "Cardinality Operators" $ do
+      describe "(?+)" $ do
+        it "succeeds on non-empty list" $ do
+          runMonadError (pure [1, 2, 3] ?+ "empty") `shouldBe` Right [1, 2, 3]
+        it "fails on empty list" $ do
+          runMonadError (pure ([] :: [Int]) ?+ "empty") `shouldBe` Left "empty"
+
+      describe "(?!)" $ do
+        let toErr = cardinalityErr "none" (const "too many")
+        it "extracts the single element" $ do
+          runMonadError (pure [42] ?! toErr) `shouldBe` Right 42
+        it "fails on empty" $ do
+          runMonadError (pure ([] :: [Int]) ?! toErr) `shouldBe` Left "none"
+        it "fails on multiple elements" $ do
+          runMonadError (pure [1, 2] ?! toErr) `shouldBe` Left "too many"
+
+      describe "(?∅)" $ do
+        it "succeeds on empty" $ do
+          runMonadError (pure [] ?∅ const "not empty") `shouldBe` Right ()
+        it "fails on non-empty" $ do
+          runMonadError (pure [1] ?∅ const "not empty") `shouldBe` Left "not empty"
