kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Mismatch in deserialized/serialized serial name used for sealed value class.

Open christiandeange opened this issue 2 years ago • 2 comments

Describe the bug

When serializing a sealed value class, the serial name of the inner class is embedded into the resulting JSON string. However, the produced string cannot be deserialized, as it is the outer class's serial name (ie: the sealed value class itself) that should be used here.

To Reproduce

@Serializable
sealed interface Sealed

@JvmInline
@Serializable
@SerialName("outer")
value class SealedOuter(val inner: Inner) : Sealed

@Serializable
@SerialName("inner")
data class Inner(val n: Int)

val sealed: Sealed = SealedOuter(Inner(10))

Json.encodeToString(sealed)                                     // {"type":"inner","n":10}
Json.decodeFromString<Sealed>("""{"type":"inner","n":10}""")    // ERROR: Polymorphic serializer was not found for class discriminator 'inner'
Json.decodeFromString<Sealed>("""{"type":"outer","n":10}""")    // SealedOuter(inner=Inner(n=10))

Expected behavior

Json.encodeToString(sealed) should probably return {"type":"outer","n":10} instead, since that string would be able to be deserialized back into an equivalent instance as the original.

I used @SerialName annotations to make the example more succinct, but the same issue can be seen if using omitting that and using the fully-qualified class names by default instead.

Environment

  • Kotlin version: 1.8.20
  • Library version: 1.5.0
  • Kotlin platforms: JVM
  • Gradle version: 8.0.2

christiandeange avatar Apr 30 '23 08:04 christiandeange

Related: #2159, #2164, #2049

sandwwraith avatar May 08 '23 12:05 sandwwraith

@sandwwraith any updates on this issue?

christiandeange avatar Nov 11 '23 03:11 christiandeange