# TapirSchemaToJsonSchema does not resolve the root reference

**URL:** <https://softwaremill.community/t/tapirschematojsonschema-does-not-resolve-the-root-reference/488>\
**Category:** tapir\
**Created:** [May 7, 2025, 5:23am UTC](https://softwaremill.community/t/tapirschematojsonschema-does-not-resolve-the-root-reference/488 "2025-05-07T05:23:10Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![karelsk](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/karelsk/32/320_2.png) [@karelsk](https://softwaremill.community/u/karelsk)\
**Post date:** [May 7, 2025, 5:23am UTC](https://softwaremill.community/t/tapirschematojsonschema-does-not-resolve-the-root-reference/488/1 "2025-05-07T05:23:10Z")

</div>

We have a coproduct where the root trait is referenced from a child. When we try to convert auto-generated tapir schema to apispec json schema the child schemas are referenced from `$defs` object but not the root schema.

In [tapir/docs/apispec-docs/src/main/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchema.scala at 303bb741d762deb1c92639667e0dc9832304bbab · softwaremill/tapir · GitHub](https://github.com/softwaremill/tapir/blob/303bb741d762deb1c92639667e0dc9832304bbab/docs/apispec-docs/src/main/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchema.scala#L21)  
the root schema reference is actually dropped.

The reference remains as a class full name and that does not work in validation where a correct URI is expected.

Is there some simple solution or workaround? It works for other recursive hierarchies where the root is not referenced. So one solution would be to introduce a root wrapper and then to remove the wrapper from the resulting Json schema (not that simple).

Example:

```auto
import com.networknt.schema.*
import com.networknt.schema.SpecVersion.VersionFlag
import com.networknt.schema.{ InputFormat, JsonSchema }
import io.circe.generic.extras.Configuration
import io.circe.{ Printer, Encoder }
import io.circe.syntax.*
import io.circe.generic.extras.semiauto.*
import sttp.apispec.circe.*
import sttp.tapir.Schema
import sttp.tapir.docs.apispec.schema.TapirSchemaToJsonSchema
import sttp.tapir.generic.auto.SchemaDerivation

object unresolved extends SchemaDerivation {
  sealed trait Model
  final case class SetModel(set: Set[Model]) extends Model
  final case class LeafModel(num: Int) extends Model

  implicit val configuration: Configuration = Configuration.default
  implicit val setModelEncoder: Encoder[SetModel] = deriveConfiguredEncoder
  implicit val leafModelEncoder: Encoder[LeafModel] = deriveConfiguredEncoder
  implicit val modelEncoder: Encoder[Model] = Encoder.instance {
    case x: SetModel => x.asJson
    case x: LeafModel => x.asJson
  }

  def main(args: Array[String]): Unit = {
    val printer: Printer = Printer.spaces2
    val jsf: JsonSchemaFactory = JsonSchemaFactory.getInstance(VersionFlag.V202012)
    val svc: SchemaValidatorsConfig = SchemaValidatorsConfig.builder().build()

    val schema = implicitly[Schema[Model]]
    val apispecSchema = TapirSchemaToJsonSchema(schema, markOptionsAsNullable = true)
    val jsonSchema = apispecSchema.asJson
    val jsonSchemaString = jsonSchema.printWith(printer)
    println(s"schema: $jsonSchemaString")

    val sample = SetModel(Set(LeafModel(1), LeafModel(2)))
    val sampleString = sample.asJson.printWith(printer)
    println(s"sample = $sampleString")

    val schemaValidator: JsonSchema = jsf.getSchema(jsonSchemaString, svc)
    val result = schemaValidator.validate(sampleString, InputFormat.JSON, OutputFormat.DEFAULT)
    println(s"result = ${result.toArray.mkString("\n")}")
  }
}

```

---

<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:** [May 13, 2025, 9:57am UTC](https://softwaremill.community/t/tapirschematojsonschema-does-not-resolve-the-root-reference/488/2 "2025-05-13T09:57:30Z")

</div>

Can you create an issue with the actual, and expected schemas that should be created in this case? I suppose there is a way in json schema to reference the root?

---

<div class="post-metadata">

**Author:** ![karelsk](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/karelsk/32/320_2.png) [@karelsk](https://softwaremill.community/u/karelsk)\
**Post date:** [May 16, 2025, 8:49am UTC](https://softwaremill.community/t/tapirschematojsonschema-does-not-resolve-the-root-reference/488/3 "2025-05-16T08:49:02Z")

</div>

Thank you Adam, I created the [issue](https://github.com/softwaremill/tapir/issues/4589#issue-3068289625).
