Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serializer expects discriminator to decode but does not incluide when encoding #1936

Closed
JonoAugustine opened this issue May 13, 2022 · 3 comments
Labels

Comments

@JonoAugustine
Copy link

My polymorphic serializer expects a class discriminator when decoding, but does not include one when encoding.

I have a multi-module project with a client, server, and common modules. In common, the Json module is defined for the sealed class Action like this:

val jsonConfig = Json {
    prettyPrint = true
    ignoreUnknownKeys = true
    encodeDefaults = true
    serializersModule = SerializersModule {
        polymorphic(Action::class) {
            subclass(CreateMatch::class)
            subclass(Start::class)
            //etc
        }
}

Using jsonConfig.encodeToString(Start()) will produce a string { "match": { ... } } with no class discriminator, which afaik is the expected behavior for sealed classes (closed polymorphism). The problem arises when trying to decode from string, where jsonConfig.decodeFromString<Action>(string) will throw an exception regarding the missing discriminator:

Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null')
JSON input: {"player":{"id":"ab2b1b63-6c4e","matchID":null,"name":"ab2b1b63-6c4e"}}

Aside from using open polymorphism and forcing the encoder to include a discriminator, what are some solutions to this issue?

Thanks in advance

@sandwwraith
Copy link
Member

That's the common polymorphism pitfall. From the docs:

When serializing polymorphic class hierarchies you must ensure that the compile-time type of the serialized object is a polymorphic one, not a concrete one.

To solve your problem, try to do the following: jsonConfig.encodeToString<Action>(Start())

Also see: #1194, #1247

@qwwdfsad
Copy link
Collaborator

That's the common polymorphism pitfall.

Maybe it's time to design/introduce the corresponding inspection?

@sandwwraith
Copy link
Member

@qwwdfsad I doubt it's possible. Better to implement #1247

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants