kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

serializer(KType) doesn't find types with custom serializers

Open CLOVIS-AI opened this issue 3 weeks ago • 7 comments

Describe the bug

serializer(KType) and serializerOrNull(KType) find types annotated with @Serializable but not types annotated with @Serializable(with = …)

To Reproduce Playground link: https://pl.kotl.in/GPVEn019Z

Expected behavior

The behavior of serializer(KType) should be identical for any class annotated with @Serializable, whether or not it uses with =.

Environment

  • Kotlin version: 2.2.21
  • Library version: 1.9.0
  • Kotlin platforms:
    • All non-JVM platforms
    • In my own project, this bug doesn't display itself on the JVM. However, the minimal reproducer I linked above on the Kotlin Playground does exhibit the bug, so I'm not sure what's going on.
  • Gradle version: 9.2, but I don't think it matters

CLOVIS-AI avatar Nov 26 '25 21:11 CLOVIS-AI

For more context about the real-world case, see here and here (both on KotlinLang Slack).

CLOVIS-AI avatar Nov 26 '25 21:11 CLOVIS-AI

I've had a bit of a look at it. I'm not sure why the playground version doesn't work. The actual implementation of the runtime lookup works as follows:

Details

### JVM Find (using reflection) the function `serializer` (with a correct number of `KSerializer` arguments) in the (potentially named) companion object. (note that this would mean doing this by hand would work, but the plugin fails if the annotation is present and the function too).

JS

Dynamically invoke the serializer function on the Companion member of the type object.

Native and WASM

Uses associated objects (part of the standard library) to store either the serializer or a factory for instantiating it.

Actually running the test (SerializersLookupNamedCompanionTest) in the library test suite (copying in your C implementation) works as expected. This looks more like an issue either with the playground or the use of an inconsistent or older version of the library.

pdvrieze avatar Nov 27 '25 10:11 pdvrieze

This looks like a weird Kotlin Playground bug. If you use this code elsewhere, it works as expected on JVM. Did you say it doesn't on Native?

sandwwraith avatar Nov 27 '25 15:11 sandwwraith

On my own project, I do see it work correctly on the JVM. However, I see the same behavior as the playground on JS, WasmJS, Wasm WASI and LinuxX64.

CLOVIS-AI avatar Nov 27 '25 15:11 CLOVIS-AI

It may well be related to https://github.com/Kotlin/kotlinx.serialization/issues/2382: non-generic serializers on JS can't be classes and must be objects.

This bug just caught me out again for possibly the third time. Would be great if a meaningful error message could be triggered in such cases.

SimonCJacobs avatar Nov 27 '25 19:11 SimonCJacobs

@SimonCJacobs In this case the serializer is an object so that cannot be the issue. Also, the code works when put into the library test suite, so there is something more to the issue.

pdvrieze avatar Nov 28 '25 10:11 pdvrieze

Oh wow. It is #2382. I just replaced the serializer in the real-world project by an object and it fixes the issue. Thankfully, in my case, it's fine to make the serializer an object.

I guess this leaves this issue as tracking for the Playground behavior itself, but at least I have a solution for the real world. Thanks!

CLOVIS-AI avatar Nov 28 '25 18:11 CLOVIS-AI