Here's a trivial example to demonstrate the problem:
import com.sksamuel.avro4s.*
case class Foo[A](a: List[A]) derives SchemaFor
case class Bar(f1: Foo[Int], f2: Foo[String]) derives SchemaFor
@main def main = println(AvroSchema[Bar])
This crashes with the following error:
[error] org.apache.avro.SchemaParseException: Can't redefine: Foo__A
[error] at org.apache.avro.Schema$Names.put(Schema.java:1604)
The problem is that when a SchemaFor instance is derived for a generic type, it doesn't know about the concrete type that is going to be substituted for A, and so it just inserts A. So you get the name Foo__A twice (because there are two Foo fields in Bar, and Avro doesn't like that.
This is not an easy problem to solve because to insert the correct Avro typename into the schema for Foo, we would need access to the SchemaFor[A] instance for A. The derives clause actually gives that to us, but Magnolia doesn't, it only gives you the SchemaFor[List[A]] instance.
Removing the derives clause for Foo fixes the problem, but obviously that is also not ideal.
Here's a trivial example to demonstrate the problem:
This crashes with the following error:
The problem is that when a
SchemaFor
instance is derived for a generic type, it doesn't know about the concrete type that is going to be substituted forA
, and so it just insertsA
. So you get the nameFoo__A
twice (because there are twoFoo
fields inBar
, and Avro doesn't like that.This is not an easy problem to solve because to insert the correct Avro typename into the schema for
Foo
, we would need access to theSchemaFor[A]
instance forA
. Thederives
clause actually gives that to us, but Magnolia doesn't, it only gives you theSchemaFor[List[A]]
instance.Removing the
derives
clause forFoo
fixes the problem, but obviously that is also not ideal.