zio-http icon indicating copy to clipboard operation
zio-http copied to clipboard

getting `BinaryCodec` from `Schema` for sealed trait hierarchy doesn't work

Open dontgitit opened this issue 1 month ago • 3 comments

Describe the bug

Trying to get a BinaryCodec from a Schema fails for sealed trait / case object hierarchies.

Given the following class hierarchy:

sealed trait Foo derives Schema
case object Foo1 extends Foo
sealed trait Bar extends Foo
case object Bar1 extends Bar

zio.http.codec.TextBinaryCodec.fromSchema[Foo] throws:

java.lang.ClassCastException: class zio.schema.Schema$Enum1 cannot be cast to class zio.schema.Schema$CaseClass0 (zio.schema.Schema$Enum1 and zio.schema.Schema$CaseClass0 are in unnamed module of loader 'app')
[info]  at zio.http.codec.TextBinaryCodec$.$anonfun$1(TextBinaryCodec.scala:58)
[info]  at scala.collection.ArrayOps$.map$extension(ArrayOps.scala:936)
[info]  at zio.Chunk$Arr.mapChunk(Chunk.scala:1774)
[info]  at zio.ChunkLike.map(ChunkLike.scala:125)
[info]  at zio.ChunkLike.map$(ChunkLike.scala:39)
[info]  at zio.Chunk.map(Chunk.scala:44)
[info]  at zio.http.codec.TextBinaryCodec$.fromSchema(TextBinaryCodec.scala:57)

and val jsonCodec = zio.schema.codec.JsonCodec.schemaBasedBinaryCodec[Foo] succeeds, but using it via jsonCodec.encode(Foo1) fails with:

java.lang.ClassCastException: class zio.schema.Schema$Enum1 cannot be cast to class zio.schema.Schema$CaseClass0 (zio.schema.Schema$Enum1 and zio.schema.Schema$CaseClass0 are in unnamed module of loader 'app')
[info]  at zio.schema.codec.JsonCodec$.zio$schema$codec$JsonCodec$JsonEncoder$$$_$caseMap$$anonfun$1(JsonCodec.scala:643)
[info]  at scala.collection.ArrayOps$.map$extension(ArrayOps.scala:936)
[info]  at zio.Chunk$Arr.mapChunk(Chunk.scala:1774)
[info]  at zio.ChunkLike.map(ChunkLike.scala:125)
[info]  at zio.ChunkLike.map$(ChunkLike.scala:39)
[info]  at zio.Chunk.map(Chunk.scala:44)
[info]  at zio.schema.codec.JsonCodec$JsonEncoder$.caseMap(JsonCodec.scala:642)
[info]  at zio.schema.codec.JsonCodec$JsonEncoder$.enumEncoder(JsonCodec.scala:651)
[info]  at zio.schema.codec.JsonCodec$JsonEncoder$.schemaEncoderSlow(JsonCodec.scala:495)
[info]  at zio.schema.codec.JsonCodec$JsonEncoder$.schemaEncoder(JsonCodec.scala:471)
[info]  at zio.schema.codec.JsonCodec$JsonEncoder$.encode(JsonCodec.scala:452)
[info]  at zio.schema.codec.JsonCodec$$anon$2.encode(JsonCodec.scala:331)
[info]  at zio.schema.codec.JsonCodec$$anon$2.encode(JsonCodec.scala:330)

To Reproduce https://scastie.scala-lang.org/tYRKPj1gSdeVmfdXcJmssw

Expected behaviour I would expect no exceptions.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information): tested on Scala 3.7.3 and 3.74, zio-http 3.5.1

dontgitit avatar Nov 18 '25 19:11 dontgitit

@dontgitit Please add more context about your use case with examples of expected JSON representation.

It would help in fixing the issue for this project and preventing similar one in https://github.com/zio/zio-blocks

plokhotnyuk avatar Dec 04 '25 11:12 plokhotnyuk

@plokhotnyuk I was trying to use it via the Endpoint API:

sealed trait Foo derives Schema
case object Foo1 extends Foo
sealed trait Bar extends Foo
case object Bar1 extends Bar

case class MyResponse(foo: Foo) derives Schema

Endpoint(Method.GET / "foo").out[MyResponse]

as for expected JSON representation... I think the most consistent representation would be to mirror what zio-json produces, but I don't have a strong opinion

dontgitit avatar Dec 05 '25 04:12 dontgitit

@plokhotnyuk I think there are two bugs. The upper stack trace looks like a zio-http bug. The lower one like a zio-schema bug

987Nabil avatar Dec 05 '25 06:12 987Nabil