Skip to content

Polymorphic Deserialization Fails with Subclass using JsonTransformingSerializer #3108

@NoMathExpectation

Description

@NoMathExpectation

Describe the bug
In polymorphic deserialization, when the target subclass is using JsonTransformingSerializer, the deserialization will fail. It seems that it forgets it is deserializing an polymorphic object.

kotlinx.serialization.json.internal.JsonDecodingException: Encountered an unknown key 'type' at element: $
Use 'ignoreUnknownKeys = true' in 'Json {}' builder or '@JsonIgnoreUnknownKeys' annotation to ignore unknown keys.
JSON input: {"type":"Sub"}
	at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
	at kotlinx.serialization.json.internal.JsonTreeDecoder.endStructure(TreeJsonDecoder.kt:292)
	at test.DecodeTest2$Sub$$serializer.deserialize(DecodeTest2.kt:15)
	at test.DecodeTest2$Sub$$serializer.deserialize(DecodeTest2.kt:15)
	at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:351)
	at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
	at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:170)
	at kotlinx.serialization.json.JsonTransformingSerializer.deserialize(JsonTransformingSerializer.kt:78)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:89)
	at kotlinx.serialization.json.Json.decodeFromString(Json.kt:149)
	at test.DecodeTest2.test(DecodeTest2.kt:33)

To Reproduce

class DecodeTest2 {
    @Serializable
    sealed class Base

    @OptIn(ExperimentalSerializationApi::class)
    @Serializable(Sub.Serializer::class)
    @KeepGeneratedSerializer
    @SerialName("Sub")
    class Sub : Base() {
        object Serializer : JsonTransformingSerializer<Sub>(generatedSerializer())
    }

    @Test
    fun test() {
        val base: Base = Sub()
        val jsonText = Json.encodeToString(base)
        println(jsonText)
        val decodedBase: Base = Json.decodeFromString(jsonText) // this will fail
        println(decodedBase)
    }
}

Expected behavior
The deserialization will succeed with a Sub instance.

Environment

  • Kotlin version: 2.2.20
  • Library version: 1.9.0
  • Kotlin platforms: JVM

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions