I have this sealed interface, with default deseria...
# serialization
v
I have this sealed interface, with default deserializer as shown in the docs, but it crashes > kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 145: Serializer for subclass ‘POLL’ is not found in the polymorphic scope of ‘PostMediaDto’ at path: $.media Can anyone tell me when I am doing wrong here?
Copy code
@Serializable
sealed interface PostMediaDto {

    companion object {
        val serializerModule = SerializersModule {
            polymorphic(PostMediaDto::class){
                subclass(Image::class)
                subclass(Link::class)
                defaultDeserializer { NotImplemented.serializer() }
            }
        }
    }

    @Serializable
    @SerialName("IMAGE")
    data class Image(val data: List<String>) : PostMediaDto

    @Serializable
    @SerialName("LINK")
    data class Link(val data: List<String>) : PostMediaDto

    @Serializable
    data object NotImplemented : PostMediaDto

}
j
You are missing a subclass for "POLL"
v
@jw I added the defaultDeserializer to handle cases when the subclass for that type is missing
Which is not working
j
So I believe that's only invoked when the class name is known, which isn't the case when custom names are used since the classname is no longer available. I would have to double check the implementation.
j
Maybe not. Looks like the discriminator flows into the lookup and the "className" is just historical baggage
That then is this https://github.com/Kotlin/kotlinx.serialization/blob/1116f5f13a957feecda47d5e08b0aa335fc010fa/core/commonMain/src/kotlinx/serialization/PolymorphicSerializer.kt#L98-L102 which is where the exception is originating, which means the first function call is returning null
everything looks fine. what version are you using?
v
1.6.2 @jw
@jw is this
defaultDeserializer
not possible to be used with closed polymorphism using sealed interfaces? Does it need to be open polymorphism?
I tried to reproduce this with a small sample, and it seems to work fine This is a
kotlin("jvm")
project
Copy code
@Serializable
sealed interface Animal {


    companion object {
        val serialModule = SerializersModule {
            polymorphic(Animal::class){
                subclass(Cat::class)
                subclass(Dog::class)
                defaultDeserializer { Human.serializer() }
            }
        }
    }

    @Serializable
    @SerialName("CAT")
    data object Cat: Animal

    @Serializable
    @SerialName("DOG")
    data object Dog: Animal

    @Serializable
    data object Human: Animal

}

fun main(){

    val json = """
        [
            {
                "type": "DOG"
            },
            {
                "type": "CAT"
            },
            {
                "type": "RABBIT"
            }
        ]
    """.trimIndent()

    val serializer = Json {
        this.serializersModule = SerializersModule {
            include(Animal.serialModule)
        }
    }

    serializer.decodeFromString<List<Animal>>(json)
        .also { println(it.toString()) }

}