diff --git a/registry-aeson.cabal b/registry-aeson.cabal
--- a/registry-aeson.cabal
+++ b/registry-aeson.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           registry-aeson
-version:        0.2.3.1
+version:        0.2.3.2
 synopsis:       Aeson encoders / decoders
 description:    This library provides encoders / decoders which can be easily customized for the Aeson format.
 category:       Data
diff --git a/src/Data/Registry/Aeson/TH/Decoder.hs b/src/Data/Registry/Aeson/TH/Decoder.hs
--- a/src/Data/Registry/Aeson/TH/Decoder.hs
+++ b/src/Data/Registry/Aeson/TH/Decoder.hs
@@ -90,9 +90,9 @@
 makeMatchClause :: ThOptions -> Name -> [Type] -> Con -> MatchQ
 makeMatchClause thOptions typeName allTypes c = do
   ts <- typesOf c
-  constructorTypes <- fmap (\(_,_,k) -> k) <$> indexConstructorTypes allTypes ts
+  constructorTypes <- fmap (\(_,n,k) -> (n, k)) <$> indexConstructorTypes allTypes ts
   cName <- makeName thOptions <$> nameOf c
-  let fieldsP = listP $ (\i -> varP $ mkName ("v" <> P.show i)) <$> constructorTypes
+  let fieldsP = listP $ (\(n, _) -> varP $ mkName ("v" <> P.show n)) <$> constructorTypes
   match
     (conP (mkName "ToConstructor") [litP (StringL . P.show $ cName), fieldsP])
     (normalB (applyDecoder thOptions typeName cName constructorTypes))
@@ -107,15 +107,15 @@
   match (varP $ mkName "_1") (normalB (appE (conE $ mkName "Left") errorMessage)) []
 
 -- ConstructorName <$> decodeFieldValue d1 o1 <*> decodeFieldValue d2 o2 ...
-applyDecoder :: ThOptions -> Name -> Name -> [Int] -> ExpQ
+applyDecoder :: ThOptions -> Name -> Name -> [(Int, Int)] -> ExpQ
 applyDecoder _thOptions _typeName cName [] = appE (varE $ mkName "pure") (conE cName)
-applyDecoder thOptions typeName cName (n : ns) = do
+applyDecoder thOptions typeName cName (nk : nks) = do
   let cons = appE (varE $ mkName "pure") (conE cName)
-  foldr (\i r -> appE (appE (varE (mkName "ap")) r) $ decodeAt i) (appE (appE (varE (mkName "ap")) cons) $ decodeAt n) (reverse ns)
+  foldr (\i r -> appE (appE (varE (mkName "ap")) r) $ decodeAt i) (appE (appE (varE (mkName "ap")) cons) $ decodeAt nk) (reverse nks)
   where
-    decodeAt i =
+    decodeAt (n, k) =
       varE (mkName "decodeFieldValue")
-        `appE` varE (mkName ("d" <> P.show i))
+        `appE` varE (mkName ("d" <> P.show k))
         `appE` (litE . StringL . P.show . makeName thOptions $ typeName)
         `appE` (litE . StringL . P.show . makeName thOptions $ cName)
-        `appE` varE (mkName ("v" <> P.show i))
+        `appE` varE (mkName ("v" <> P.show n))
diff --git a/test/Test/Data/Registry/Aeson/DecoderSpec.hs b/test/Test/Data/Registry/Aeson/DecoderSpec.hs
--- a/test/Test/Data/Registry/Aeson/DecoderSpec.hs
+++ b/test/Test/Data/Registry/Aeson/DecoderSpec.hs
@@ -124,6 +124,11 @@
     "{'InPerson':[{'email':{'_email':'me@here.com'},'identifier':123,'f1':1,'f2':1},{'_datetime':'2022-04-18T00:00:12Z'}]}"
     "Cannot decode the type 'Delivery' >> (InPerson) unknown fields: f1, f2"
 
+test_types_th_index_error = test "error with TH when 2 fields have the same type" $ do
+  -- this code did not compile before
+  let _ = $(makeDecoder ''Stats) <: jsonDecoder @Int <: defaultDecoderOptions
+  success
+
 test_decode_map = test "decode map" $ do
   let ds =
         decodeMapOf @Name @Int
