-
Notifications
You must be signed in to change notification settings - Fork 635
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
encodeToJsonElement on an inline class throws "No tag in stack for requested element" #1774
Comments
Actually, their implementation is very different, because the string is decoded/encoded one-by-one token, while JsonElement is encoded via an internal map structure. That's also the source of the bug — top-level value classes simply can't provide the key for this map. It also wasn't working for primitives but was fixed (#465) before value classes landed in serialization |
Thanks for your reaction and for quickly fixing this specific bug. Just to be annoying, I've looked at that commit and came up with some more cases where I think this error would still occur. Please see TaggedEncoderUndescriptiveTest in https://github.com/bartvanheukelom/jbali/blob/java17/src/jvmTest/java/org/jbali/kotser/TaggedEncoderBugTest.kt As to the JsonEncoder implementation, I understand that it's different and that's what causes these bugs. In my original comment I actually meant to say that, purely seen from the outside (as if it didn't exist yet), I would think they should have 80% in common, since that seems the most practical. Consider that something like this does work:
could |
So you're telling about the case where we provide a custom serializer with CONTEXTUAL descriptor that sometimes calls plain I think this is a bit out of the scope of this issue and should be considered in #1775 |
It's two cases:
Update: actually the problem in case 1 is not the direct use of The underlying real issue is that any CONTEXTUAL serializer will not be able to properly answer needTopLevelTag without also being given the actual value that should be encoded. But since it's only called by encodeSerializableValue, that looks like an easy fix. |
I also added a test for
and it made sense. Then I was kind of surprised that the write side isn't "mirrorred" but instead JsonTreeEncoder chooses when to delegate to JsonPrimitiveEncoder.
But I don't know enough about the internals to give any value judgement of that :) |
I see, top-level |
Hm, it seems that it should work without additional handling, because first contextual serializer resolves actual serializer, and only after the |
I seem to be having the same type of problem, with a value class wrapping |
Can this issue be reopened, please? The List-wrapping inline class scenario is trivial to reproduce via Json serialization (
|
I'm hitting the same issue with a non-list repro. On top of the encoding bug, I'm seeing an error in the decoding path as well: @Serializable
@JvmInline
value class Outer(val inner: Inner)
@Serializable
data class Inner(val n: Int)
val o = Outer(Inner(10))
Json.encodeToJsonElement(Outer.serializer(), o) // throws SerializationException("No tag in stack for requested element")
val elem = json.parseToJsonElement("""{"n":10}""")
Json.decodeFromJsonElement(Outer.serializer(), elem) // throws IndexOutOfBoundsException("Index -1 out of bounds for length 0") |
I'm able to reproduce @jasonxh's issue on Kotlinx serialization Json.decodeFromJsonElement(Outer.serializer(), elem) // java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
Json.decodeFromJsonElement<Outer>(elem) // java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
Json.decodeFromString<Outer>(json.encodeToString(elem)) // Outer(inner=Inner(n=10)) Is there any acknowledgement from the Kotlin team that this error will be looked at soon? It was reopened months ago with little to no activity since then and is fairly simple to reproduce. |
TBH I've missed the fact that it was reopened. I'll revisit this soon. |
- Value class is located at top-level, but wraps non-primitive and thus does not fall in 'primitive on top-level' branch - Value class is a subclass in a polymorphic hierarchy, but either is primitive or explicitly recorded without type info Note that type info is omitted in the latter case and 'can't add type info to primitive' error is not thrown deliberately, as there seems to be use-cases for that. Fixes #1774 Fixes #2159
- Value class is located at top-level, but wraps non-primitive and thus does not fall in 'primitive on top-level' branch - Value class is a subclass in a polymorphic hierarchy, but either is primitive or explicitly recorded without type info Note that type info is omitted in the latter case and 'can't add type info to primitive' error is not thrown deliberately, as there seems to be use-cases for that. Fixes Kotlin#1774 Fixes Kotlin#2159
I got this problem again with this code. Probably some kind of misuse of the serializers?
|
Describe the bug
Encoding a value of that class to a JSON string works as expected, but
encodeToJsonElement
throws the exception in the title.This only occurs when serializing the value directly. It works as expected when embedded in a data class.
It can be worked around by creating a custom serializer that effectively does the same thing as the generated one would.
To Reproduce
For a unit test that reproduces it and shows various workarounds that do work, see https://github.com/bartvanheukelom/jbali/blob/java17/src/jvmTest/java/org/jbali/kotser/TaggedEncoderBugTest.kt
Excepted Behaviour
Environment
The text was updated successfully, but these errors were encountered: