diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Revision history for railroad
 
+## 0.1.2.1 -- 2026-10-11
+* Fix overlapping instances: `Either e (Maybe a)`, `Maybe (Maybe a)`, `Either e Bool` and the like
+  did not compile when used with `?`, so nested layers could not be peeled (the README's first
+  example did not compile). The outermost layer is now peeled first, as documented; lists and other
+  traversables inside a layer behave as before. Tests added, including the README example.
+
 ## 0.1.2.0 -- 2026-10-11
 * Add the fallback operator `(?|)`: runs the left action, and only if it fails runs the right one.
   The two sides can be different structures (`Maybe`, `Either`, ...) with the same success type, the
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.2.0
+version:            0.1.2.1
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             Frederik Kallstrup Mastratisi
diff --git a/src/Railroad.hs b/src/Railroad.hs
--- a/src/Railroad.hs
+++ b/src/Railroad.hs
@@ -53,18 +53,20 @@
     Success a -> Right a
   -- validation :: (e -> b) -> (a -> b) -> Validation e a -> b
 
-instance (Traversable t, CErr (t Bool) ~ (), CRes (t Bool) ~ t ())
+-- The traversable instances overlap the base ones for e.g. @Either e (Maybe a)@. They are
+-- INCOHERENT so the base instance wins and the outer layer is peeled first (@m ? e1 ? e2@).
+instance {-# INCOHERENT #-} (Traversable t, CErr (t Bool) ~ (), CRes (t Bool) ~ t ())
     => Bifurcate (t Bool) where
   bifurcate = bifurcate . sequenceA . fmap bifurcate
   -- Bool is not Applicative, so we need to map to Either first
-instance (Traversable t, CErr (t (Maybe a)) ~ (), CRes (t (Maybe a)) ~ t a)
+instance {-# INCOHERENT #-} (Traversable t, CErr (t (Maybe a)) ~ (), CRes (t (Maybe a)) ~ t a)
     => Bifurcate (t (Maybe a)) where
   bifurcate = bifurcate . sequenceA
-instance (Traversable t, CErr (t (Either e a)) ~ e, CRes (t (Either e a)) ~ t a)
+instance {-# INCOHERENT #-} (Traversable t, CErr (t (Either e a)) ~ e, CRes (t (Either e a)) ~ t a)
     => Bifurcate (t (Either e a)) where
   bifurcate = sequenceA
   -- pedagogically: bifurcate = bifurcate . sequenceA
-instance (Traversable t, Semigroup e, CErr (t (Validation e a)) ~ e, CRes (t (Validation e a)) ~ t a)
+instance {-# INCOHERENT #-} (Traversable t, Semigroup e, CErr (t (Validation e a)) ~ e, CRes (t (Validation e a)) ~ t a)
     => Bifurcate (t (Validation e a)) where
   bifurcate = bifurcate . sequenceA
 
diff --git a/test/Railroad/MonadErrorSpec.hs b/test/Railroad/MonadErrorSpec.hs
--- a/test/Railroad/MonadErrorSpec.hs
+++ b/test/Railroad/MonadErrorSpec.hs
@@ -102,3 +102,21 @@
       it "needs nothing special for Maybe sources" $ do
         runCount (pure (Nothing :: Maybe Int) ?|<> pure Nothing ? "none")
           `shouldBe` (Left "none", 0)
+
+    describe "Layered structures (the outermost layer is peeled first)" $ do
+      it "peels Either of Maybe one layer at a time" $ do
+        runMonadError (pure (Right (Just 1) :: Either String (Maybe Int)) ? "outer" ? "inner") `shouldBe` Right 1
+        runMonadError (pure (Right Nothing :: Either String (Maybe Int)) ? "outer" ? "inner") `shouldBe` Left "inner"
+        runMonadError (pure (Left "x" :: Either String (Maybe Int)) ? "outer" ? "inner") `shouldBe` Left "outer"
+      it "peels Maybe of Maybe and Either of Bool" $ do
+        runMonadError (pure (Just Nothing :: Maybe (Maybe Int)) ? "o" ? "i") `shouldBe` Left "i"
+        runMonadError (pure (Right False :: Either String Bool) ? "db" ? "denied") `shouldBe` Left "denied"
+      it "runs the README example" $ do
+        let readmeExample :: Either String Int
+            readmeExample = runExcept $ do
+              x <- pure (Just 2) ? "Value missing"
+              y <- pure (Right $ Just 1) ? "Outer fail" ? "Inner fail"
+              z <- pure [Just 4] ? "List failed" ?! const "Not a single element"
+              q <- pure Nothing ?~ 1
+              pure (x + y + z + q)
+        readmeExample `shouldBe` Right 8
diff --git a/test/RailroadSpec.hs b/test/RailroadSpec.hs
--- a/test/RailroadSpec.hs
+++ b/test/RailroadSpec.hs
@@ -150,3 +150,26 @@
     it "needs nothing special for Maybe sources" $ do
       runCount (pure (Nothing :: Maybe Int) ?|<> pure Nothing ? "none")
         `shouldBe` (Left "none", 0)
+
+  describe "Layered structures (the outermost layer is peeled first)" $ do
+    it "peels Either of Maybe one layer at a time" $ do
+      let ok = pure (Right (Just 1)) :: Eff '[Error String] (Either String (Maybe Int))
+      runRail (ok ? "outer" ? "inner") `shouldBe` Right 1
+      runRail (pure (Right Nothing :: Either String (Maybe Int)) ? "outer" ? "inner") `shouldBe` Left "inner"
+      runRail (pure (Left "x" :: Either String (Maybe Int)) ? "outer" ? "inner") `shouldBe` Left "outer"
+
+    it "peels Maybe of Maybe" $ do
+      runRail (pure (Just (Just 1) :: Maybe (Maybe Int)) ? "o" ? "i") `shouldBe` Right 1
+      runRail (pure (Just Nothing :: Maybe (Maybe Int)) ? "o" ? "i") `shouldBe` Left "i"
+      runRail (pure (Nothing :: Maybe (Maybe Int)) ? "o" ? "i") `shouldBe` Left "o"
+
+    it "peels Either of Bool" $ do
+      runRail (pure (Right True :: Either String Bool) ? "db" ? "denied") `shouldBe` Right ()
+      runRail (pure (Right False :: Either String Bool) ? "db" ? "denied") `shouldBe` Left "denied"
+      runRail (pure (Left "x" :: Either String Bool) ? "db" ? "denied") `shouldBe` Left "db"
+
+    it "peels Either of Either" $ do
+      runRail (pure (Right (Left "in") :: Either String (Either String Int)) ? "out" ?? id) `shouldBe` Left "in"
+
+    it "still traverses a list inside a layer" $ do
+      runRail (pure (Just [Just 1, Just 2 :: Maybe Int]) ? "o" ? "i") `shouldBe` Right [1, 2]
