Closed
Description
Describe the bug
When serializing a sealed interface's generic property with a directly serializable type (e.g., Int or another @serializable class), the Kotlinx Serialization library incorrectly attempts polymorphic serialization, leading to a SerializationException.
To Reproduce
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
@Serializable
sealed interface Test<X>
{
val x: X
}
@Serializable
data class Test1<Y>(override val x: Y): Test<Y>
@Serializable
data class Test2(val x: Int)
fun main()
{
val json = Json {
serializersModule = SerializersModule {
contextual(Int::class, Int.serializer())
contextual(Test2::class, Test2.serializer())
}
}
val x: Test<Int> = Test1(1)
val y: Test<Test2> = Test1(Test2(1))
runCatching { json.encodeToString(x) }.onFailure(Throwable::printStackTrace) // error
runCatching { json.encodeToString(y) }.onFailure(Throwable::printStackTrace) // error
}
error:
kotlinx.serialization.SerializationException: Serializer for subclass 'Int' is not found in the polymorphic scope of 'Any'.
Check if class with serial name 'Int' exists and serializer is registered in a corresponding SerializersModule.
To be registered automatically, class 'Int' has to be '@Serializable', and the base class 'Any' has to be sealed and '@Serializable'.
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:102)
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:114)
at kotlinx.serialization.PolymorphicSerializerKt.findPolymorphicSerializer(PolymorphicSerializer.kt:109)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:250)
at kotlinx.serialization.encoding.AbstractEncoder.encodeSerializableElement(AbstractEncoder.kt:80)
at Test1.write$Self$KotlinTest(Main2.kt:12)
at Test1$$serializer.serialize(Main2.kt:12)
at Test1$$serializer.serialize(Main2.kt:12)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:259)
at kotlinx.serialization.json.internal.JsonStreamsKt.encodeByWriter(JsonStreams.kt:99)
at kotlinx.serialization.json.Json.encodeToString(Json.kt:125)
at Main2Kt.main(Main2.kt:32)
at Main2Kt.main(Main2.kt)
kotlinx.serialization.SerializationException: Serializer for subclass 'Test2' is not found in the polymorphic scope of 'Any'.
Check if class with serial name 'Test2' exists and serializer is registered in a corresponding SerializersModule.
To be registered automatically, class 'Test2' has to be '@Serializable', and the base class 'Any' has to be sealed and '@Serializable'.
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:102)
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:114)
at kotlinx.serialization.PolymorphicSerializerKt.findPolymorphicSerializer(PolymorphicSerializer.kt:109)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:250)
at kotlinx.serialization.encoding.AbstractEncoder.encodeSerializableElement(AbstractEncoder.kt:80)
at Test1.write$Self$KotlinTest(Main2.kt:12)
at Test1$$serializer.serialize(Main2.kt:12)
at Test1$$serializer.serialize(Main2.kt:12)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:259)
at kotlinx.serialization.json.internal.JsonStreamsKt.encodeByWriter(JsonStreams.kt:99)
at kotlinx.serialization.json.Json.encodeToString(Json.kt:125)
at Main2Kt.main(Main2.kt:33)
at Main2Kt.main(Main2.kt)
Expected behavior
no error and successful serialization
Environment
- Kotlin version: 2.1.10
- Library version: 1.8.0
- Kotlin platforms: JVM
- Gradle version: 8.7
My English is not good, and some of the above content is from AI translation. If it is inaccurate, please forgive me.