Skip to content

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

@christiandeange

Description

@christiandeange

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions