diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
 Unreleased
 ----------
 
+3.2.2
+-----
+
+- Fix bug with infinite recursion in GToSchema [#37](https://github.com/biocad/openapi3/pull/37).
+
 3.2.1
 -----
 
diff --git a/openapi3.cabal b/openapi3.cabal
--- a/openapi3.cabal
+++ b/openapi3.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                openapi3
-version:             3.2.1
+version:             3.2.2
 
 synopsis:            OpenAPI 3.0 data model
 category:            Web, Swagger, OpenApi
@@ -28,7 +28,7 @@
    || ==8.8.4
    || ==8.10.7
    || ==9.0.2
-   || ==9.2.1
+   || ==9.2.2
 
 custom-setup
   setup-depends:
@@ -70,7 +70,7 @@
 
   build-depends:
       mtl              >=2.2.2   && <2.3
-    , text             >=1.2.3.1 && <1.3
+    , text             >=1.2.3.1 && <2.1
 
   -- other dependencies
   build-depends:
diff --git a/src/Data/OpenApi/Internal/Schema.hs b/src/Data/OpenApi/Internal/Schema.hs
--- a/src/Data/OpenApi/Internal/Schema.hs
+++ b/src/Data/OpenApi/Internal/Schema.hs
@@ -945,10 +945,13 @@
         case schema ^. items of
           Just (OpenApiItemsArray [_]) -> fieldSchema
           _ -> do
-            declare defs
-            return (unnamed schema)
+            -- We have to run recordSchema instead of just using its defs,
+            -- since those can be recursive and will lead to infinite loop,
+            -- see https://github.com/biocad/openapi3/pull/37
+            NamedSchema _ schema' <- recordSchema
+            return (unnamed schema')
     where
-      (defs, NamedSchema _ schema) = runDeclare recordSchema mempty
+      (_, NamedSchema _ schema) = runDeclare recordSchema mempty
       recordSchema = gdeclareNamedSchema opts (Proxy :: Proxy (S1 s f)) s
       fieldSchema  = gdeclareNamedSchema opts (Proxy :: Proxy f) s
 
diff --git a/test/Data/OpenApi/CommonTestTypes.hs b/test/Data/OpenApi/CommonTestTypes.hs
--- a/test/Data/OpenApi/CommonTestTypes.hs
+++ b/test/Data/OpenApi/CommonTestTypes.hs
@@ -863,6 +863,129 @@
 }
 |]
 
+-- ========================================================================
+-- Natural Language (single field data with recursive fields)
+-- ========================================================================
+
+data Predicate
+  = PredicateNoun    Noun
+  | PredicateOmitted Omitted
+  deriving (Eq, Ord, Read, Show, Generic)
+instance ToJSON Predicate
+instance ToSchema Predicate
+
+data Noun
+  = Noun
+  { nounSurf   :: LangWord
+  , nounModify :: [Modifier]
+  }
+  deriving (Eq, Ord, Read, Show, Generic)
+instance ToJSON Noun
+instance ToSchema Noun
+
+data LangWord
+  = LangWord
+  { langWordSurf :: String
+  , langWordBase :: String
+  }
+  deriving (Eq, Ord, Read, Show, Generic)
+instance ToJSON LangWord
+instance ToSchema LangWord
+
+data Modifier
+  = ModifierNoun     Noun
+  | ModifierOmitted  Omitted
+  deriving (Eq, Ord, Read, Show, Generic)
+instance ToJSON Modifier
+instance ToSchema Modifier
+
+newtype Omitted
+  = Omitted
+  { omittedModify :: [Modifier]
+  }
+  deriving (Eq, Ord, Read, Show, Generic)
+instance ToJSON Omitted
+instance ToSchema Omitted
+
+predicateSchemaDeclareJSON :: Value
+predicateSchemaDeclareJSON = [aesonQQ|
+[
+  {
+    "Predicate": {
+      "oneOf": [
+        {
+          "properties": {
+            "contents": { "$ref": "#/components/schemas/Noun" },
+            "tag": { "enum": ["PredicateNoun"], "type": "string" }
+          },
+          "required": ["tag", "contents"],
+          "type": "object"
+        },
+        {
+          "properties": {
+            "contents": { "$ref": "#/components/schemas/Omitted" },
+            "tag": { "enum": ["PredicateOmitted"], "type": "string" }
+          },
+          "required": ["tag", "contents"],
+          "type": "object"
+        }
+      ],
+      "type": "object"
+    },
+    "Noun": {
+      "properties": {
+        "nounModify": {
+          "items": { "$ref": "#/components/schemas/Modifier" },
+          "type": "array"
+        },
+        "nounSurf": { "$ref": "#/components/schemas/LangWord" }
+      },
+      "required": ["nounSurf", "nounModify"],
+      "type": "object"
+    },
+    "LangWord": {
+      "properties": {
+        "langWordBase": { "type": "string" },
+        "langWordSurf": { "type": "string" }
+      },
+      "required": ["langWordSurf", "langWordBase"],
+      "type": "object"
+    },
+    "Modifier": {
+      "oneOf": [
+        {
+          "properties": {
+            "contents": { "$ref": "#/components/schemas/Noun" },
+            "tag": { "enum": ["ModifierNoun"], "type": "string" }
+          },
+          "required": ["tag", "contents"],
+          "type": "object"
+        },
+        {
+          "properties": {
+            "contents": { "$ref": "#/components/schemas/Omitted" },
+            "tag": { "enum": ["ModifierOmitted"], "type": "string" }
+          },
+          "required": ["tag", "contents"],
+          "type": "object"
+        }
+      ],
+      "type": "object"
+    },
+    "Omitted": {
+      "properties": {
+        "omittedModify": {
+          "items": { "$ref": "#/components/schemas/Modifier" },
+          "type": "array"
+        }
+      },
+      "required": ["omittedModify"],
+      "type": "object"
+    }
+  },
+  { "$ref": "#/components/schemas/Predicate" }
+]
+|]
 
 -- ========================================================================
 -- TimeOfDay
diff --git a/test/Data/OpenApi/SchemaSpec.hs b/test/Data/OpenApi/SchemaSpec.hs
--- a/test/Data/OpenApi/SchemaSpec.hs
+++ b/test/Data/OpenApi/SchemaSpec.hs
@@ -59,6 +59,9 @@
   where
     (defs, s) = runDeclare (declareSchema proxy) mempty
 
+checkToSchemaDeclare :: (HasCallStack, ToSchema a) => Proxy a -> Value -> Spec
+checkToSchemaDeclare proxy js = runDeclare (declareSchemaRef proxy) mempty <=> js
+
 spec :: Spec
 spec = do
   describe "Generic ToSchema" $ do
@@ -78,6 +81,7 @@
       context "UserId (non-record newtype)" $ checkToSchema (Proxy :: Proxy UserId) userIdSchemaJSON
       context "Player (unary record)" $ checkToSchema (Proxy :: Proxy Player) playerSchemaJSON
       context "SingleMaybeField (unary record with Maybe)" $ checkToSchema (Proxy :: Proxy SingleMaybeField) singleMaybeFieldSchemaJSON
+      context "Natural Language (single field data with recursive fields)" $ checkToSchemaDeclare (Proxy :: Proxy Predicate) predicateSchemaDeclareJSON
     context "Players (inlining schema)" $ checkToSchema (Proxy :: Proxy Players) playersSchemaJSON
     context "MyRoseTree (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree) myRoseTreeSchemaJSON
     context "MyRoseTree' (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree') myRoseTreeSchemaJSON'
