# StackOverflow when try to create recursive schema on coproduct

**URL:** <https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30>\
**Category:** tapir\
**Created:** [December 12, 2022, 1:06pm UTC](https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30 "2022-12-12T13:06:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bartlomiej\_Tomala](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/bartlomiej_tomala/32/24_2.png) [@Bartlomiej\_Tomala](https://softwaremill.community/u/Bartlomiej_Tomala)\
**Post date:** [December 12, 2022, 1:06pm UTC](https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30/1 "2022-12-12T13:06:52Z")

</div>

I have a model like this

```auto
sealed trait Logic
final case class And(arr: Set[Logic]) extends Logic
final case class Expr(expr: String) extends Logic

```

I wrote schema like that

```auto
  implicit lazy val andSchema: Schema[And] = Schema.derived[And]
  implicit lazy val exprSchema: Schema[Expr] = Schema.derived[Expr]
  implicit lazy val logicSchema: Schema[Logic] = Schema(SchemaType.SCoproduct(List(andSchema, exprSchema), None) {
    case l: And => Some(SchemaWithValue(andSchema, l))
    case l: Expr => Some(SchemaWithValue(exprSchema, l))
  }, name = Some(SName("Logic")))

```

Everything compiles and I’m getting StackOverflow when running my specs for the endpoints.

I added a dummy schema for the `And` class for now. Is there a proper way to solve this issue?

```auto
  implicit def andSchema: Schema[And] = Schema[And](
    SchemaType.SProduct(List(
      SProductField.apply[And, Array[Logic]](FieldName("arr"), Schema.schemaForArray(Schema.string), a => Some(a.arr.toArray))
    )), name = Some(SName("And")))

```

---

<div class="post-metadata">

**Author:** ![adamw](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/adamw/32/28_2.png) [@adamw](https://softwaremill.community/u/adamw)\
**Post date:** [December 12, 2022, 7:48pm UTC](https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30/2 "2022-12-12T19:48:49Z")

</div>

In tapir, recursive schemes need to have a “cut-off” point, after which they are no longer recursively expanded. This is done using `SRef` - which points up in the schema tree, to a schema that is already defined. In your example, you want to have a `SCoproduct` schema for `Logic`, with two children: `SProduct` for `Expr`, and another `SProduct` for `And`. One of the fields of `And` should be a list of `SRef`s back to `Logic`.

The way it’s written now, there’s no `SRef` used anywhere. Because all schemas are defined as implicit values, the `Schema.derived[And]` simply uses `logicSchema` for the `arr` field: it’s not “aware” that any recursion takes place, so it doesn’t generate the `SRef` reference. Similarly, `logicSchema` doesn’t know about recursion, and it just reuses the `andSchema`.

The simplest solution is to derive the schema for `Logic` in one call, so that the derivation can be aware of the recursion and put the `SRef`s in teh right places:

```nohighlight
implicit lazy val logicSchema: Schema[Logic] = Schema.derived[Logic]

```

Note that this works, as deriving coproduct hierarchies is explicitly supported in Magnolia to recurse one level deep into the structure (so that the typeclass - here `Schema` is derived for all implementations of the coproduct.

This gives you the desired schema. Alternatively, you can hand-craft an `Schema[And]` which uses `SRef` for the `arr` field.

---

<div class="post-metadata">

**Author:** ![Bartlomiej\_Tomala](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/bartlomiej_tomala/32/24_2.png) [@Bartlomiej\_Tomala](https://softwaremill.community/u/Bartlomiej_Tomala)\
**Post date:** [December 14, 2022, 8:03am UTC](https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30/3 "2022-12-14T08:03:34Z")

</div>

Big thanks for that. And sorry for the stupid question. I didn’t assume that I can derive schema correctly for that complex structure and I even didn’t try this. Thanks again!

---

<div class="post-metadata">

**Author:** ![adamw](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/adamw/32/28_2.png) [@adamw](https://softwaremill.community/u/adamw)\
**Post date:** [December 14, 2022, 11:53am UTC](https://softwaremill.community/t/stackoverflow-when-try-to-create-recursive-schema-on-coproduct/30/4 "2022-12-14T11:53:41Z")

</div>

Definitely not a stupid question - recursive implicits and typeclasses for recursive structures are always tricky 🙂
