Skip to content

Kotlin object that implements several sealed interfaces fails to be serialized #2110

@yandroidUA

Description

@yandroidUA

Describe the bug

When trying to serialize an object that implements several sealed interfaces that are marked as @Serializable, library crashes with the following log:

Exception in thread "main" java.lang.IllegalArgumentException: Element with name 'unknown-error' is already registered
	at kotlinx.serialization.descriptors.ClassSerialDescriptorBuilder.element(SerialDescriptors.kt:282)
	at kotlinx.serialization.descriptors.ClassSerialDescriptorBuilder.element$default(SerialDescriptors.kt:276)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2$1$elementDescriptor$1.invoke(SealedSerializer.kt:110)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2$1$elementDescriptor$1.invoke(SealedSerializer.kt:107)
	at kotlinx.serialization.descriptors.SerialDescriptorsKt.buildSerialDescriptor(SerialDescriptors.kt:145)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2$1.invoke(SealedSerializer.kt:107)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2$1.invoke(SealedSerializer.kt:104)
	at kotlinx.serialization.descriptors.SerialDescriptorsKt.buildSerialDescriptor(SerialDescriptors.kt:145)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2.invoke(SealedSerializer.kt:104)
	at kotlinx.serialization.SealedClassSerializer$descriptor$2.invoke(SealedSerializer.kt:103)
	at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
	at kotlinx.serialization.SealedClassSerializer.getDescriptor(SealedSerializer.kt:103)
	at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:228)
	at kotlinx.serialization.json.internal.JsonStreamsKt.encodeByWriter(JsonStreams.kt:28)
	at kotlinx.serialization.json.Json.encodeToString(Json.kt:79)
	at MainKt.encode(Main.kt:12)
	at MainKt.main(Main.kt:6)

Note: If change object to the class in the object declaration, application works fine, therefore the issue impacts only Kotlin's object

Related: #1937 (It's actually the same bug, but for Kotlin's class).

To Reproduce

You can use this demo project to reproduce the issue: reproduce.zip

Code to reproduce:

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
sealed interface CustomError {

    @Serializable
    sealed interface SignInCustomError : CustomError

    @Serializable
    sealed interface SignUpCustomError : CustomError

    @Serializable
    @SerialName(TYPE_UNKNOWN_ERROR)
    object UnknownError : CustomError, SignInCustomError, SignUpCustomError

    companion object {
        private const val TYPE_UNKNOWN_ERROR = "unknown-error"
    }

}
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

fun main(args: Array<String>) {
    println("Hello World!")
    encode(CustomError.UnknownError)
}

fun encode(error: CustomError) {
    println(Json.encodeToString(error))
}

Expected behavior

An object that implements several sealed interfaces that are marked as @Serializable won't crash the program and will be serialized/deserialized in a same way as Kotlin's classes in that case.

Environment

  • Kotlin version: 1.7.20
  • Library version: 1.4.1
  • Kotlin platforms: JVM, JS, Native
  • Gradle version: 7.4.2
  • IDE version (if bug is related to the IDE): IntelliJ Idea Build #IC-222.4345.14, built on October 5, 2022
  • Other relevant context: MacOS

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions