zio/zio-json

Unable to locate the JsonDecoder for a type constructor containing a nested type.

wi101 opened this issue ยท 11 comments

Hello,

This issue appeared when updating to zio-json: 0.7.0.
Here is an example:

final case class Id[A](value: A)
object Id {
  implicit def decoder[A: JsonDecoder]: JsonDecoder[Id[A]] = DeriveJsonDecoder.gen[Id[A]]
}

final case class Person(name: String) extends AnyVal
object Person {
  implicit val decoder: JsonDecoder[Person] = DeriveJsonDecoder.gen
}


final case class People(ids: Id[Person])
object People {
  implicit val decoder: JsonDecoder[People] = DeriveJsonDecoder.gen
}

Error:

magnolia: could not find JsonDecoder.Typeclass for type Id[Person]
[error]     in parameter 'ids' of product type People
[error]   implicit val decoder: JsonDecoder[People] = DeriveJsonDecoder.gen

People.decoder cannot find the decoder for Id[Person].
There is an issue on finding the Id.decoder ..

when we manually add the decoder to Id companion object:

object Id {
    implicit val decoderIds: JsonDecoder[Id[Person]] = DeriveJsonDecoder.gen
}

The same error appears. But it works only when we add that decoder to People companion.

object People {
  implicit val decoderIds: JsonDecoder[Id[Person]] = Id.decoder
  implicit val decoder: JsonDecoder[People] = DeriveJsonDecoder.gen
}

/bounty $200

## ๐Ÿ’Ž $200 bounty โ€ข ZIO

### Steps to solve:
1. Start working: Comment /attempt #1128 with your implementation plan
2. Submit work: Create a pull request including /claim #1128 in the PR body to claim the bounty
3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Thank you for contributing to zio/zio-json!

Add a bounty โ€ข Share on socials

Attempt Started (GMT+0) Solution
๐Ÿ”ด @Anshgrover23 Jun 28, 2024, 4:11:00 PM WIP
๐Ÿ”ด @omarnagy91 Jul 9, 2024, 4:58:42 AM WIP
๐ŸŸข @ifndev Jul 29, 2024, 1:45:06 PM #1139

@wi101 I am unable to reproduce What Scala version are you using? Are the definitions all in the same file? Are you sure you have no conflicting versions in your project?

/attempt #1128

@987Nabil

This is the full example (the same file)

import zio.json.{DeriveJsonDecoder, JsonDecoder}

final case class Id[A](value: A)
object Id {
  implicit def decoder[A: JsonDecoder]: JsonDecoder[Id[A]] = DeriveJsonDecoder.gen[Id[A]]
}

final case class Person(name: String) extends AnyVal
object Person {
  implicit val decoder: JsonDecoder[Person] = DeriveJsonDecoder.gen
}


final case class People(ids: Id[Person])
object People {
  implicit val decoder: JsonDecoder[People] = DeriveJsonDecoder.gen
}

scalaVersion: 2.13.14
zioJsonVersion: 0.7.0

Hi, this issue seems stale so I gave it a shot.

What I found out:

  • PR #1115 introduced "codec derivation for types that already have encoder and decoder"
  • Faced with an error in one of the tests (same test case as this issue) with scala 2.12, it was decided to remove the feature for this specific version.
  • Turns out it doesn't work on 2.13 either

What I did:

  • I reverted the VersionSpecific code as it did not fix the issue
  • I identified the problematic line
    implicit def fromEncoderDecoder[A](implicit encoder: JsonEncoder[A], decoder: JsonDecoder[A]): JsonCodec[A] =
  • As I couldn't find a reason for the 'encoder' parameter being implicit, and found no test cases justifying it, i made it explicit again
  • Tests now passes on all Scala versions
  • Code provided by @wi101 compiles successfully
  • PR yet to be submitted...

/attempt #1128

Algora profile Completed bounties Tech Active attempts Options
@ifndev 1 bounty from 1 project
Python, C++,
TypeScript & more
Cancel attempt

๐Ÿ’ก @ifndev submitted a pull request that claims the bounty. You can visit your bounty board to reward.

Just submitted PR #1139

It's based on the assumption that making the 'encoder' parameter implicit was a mistake, so it may be wrong.
Ideally, adding a test for a specific case covered by PR #1115 would be a good idea.

Let me know if I missed something :)

Hey, when can we expect the PR to be merged? I am working on an implementation that depends on this fix.

๐ŸŽ‰๐ŸŽˆ @ifndev has been awarded $200! ๐ŸŽˆ๐ŸŽŠ