You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fields starting with lowercase non ASCII characters are silently dropped when serializingΒ #1154
I searched in the issues and found nothing similar.
I have confirmed that the same problem is not reproduced if I exclude the KotlinModule.
I searched in the issues of databind and other modules used and found nothing similar.
I have confirmed that the problem does not reproduce in Java and only occurs when using Kotlin and KotlinModule.
Describe the bug
When a field name starts with a (lowercase) non ASCII character, it is silently dropped when serialized. This behaviour did not exist in Jackson2.
Example:
data classFoo(
val ΓΈx:String = "bar",
)
Results in an empty JSON: {}
I think this happens because the field ends up with a lowercase character in the getter in Kotlin Bytecode.
E.g. val foo results in getFoo, but val ΓΈx results in getΓΈx.
To Reproduce
data classFoo(
val ΓΈx:String = "disappears",
val yΓΈ: String = "ok",
)
funmain() {
val jackson2Mapper = com.fasterxml.jackson.module.kotlin.jacksonObjectMapper()
val jackson2Json = jackson2Mapper.writeValueAsString(Foo())
println("Jackson 2: $jackson2Json")
val jackson3Mapper = tools.jackson.module.kotlin.jacksonMapperBuilder().build()
val jackson3Json = jackson3Mapper.writeValueAsString(Foo())
println("Jackson 3: $jackson3Json")
// Output:// Jackson 2: {"ΓΈx":"disappears","yΓΈ":"ok"}// Jackson 3: {"yΓΈ":"ok"}
}
Expected behavior
I expected the field to be serialized like fields consisting of ASCII characters (like it did in Jackson2), or for an error to be thrown.
Versions
Kotlin: 2.3.20
Jackson-module-kotlin: 3.1.2
Additional context
@JsonProperty can be used as a workaround.
data classWorkaround1(
@JsonProperty("ΓΈx")
valox:String,
)
data classWorkaround2(
@get:JsonProperty("ΓΈx")
val ΓΈx:String,
)
Thanks! Just want to make sure I understand the issue here before filing an issue in jackson-databind.
Consider this example:
data classFoo(
// Kotlin Bytecode: public final getΓΈx()Ljava/lang/String;val ΓΈx:String = "test",
// Kotlin Bytecode: public final getΓk()Ljava/lang/String;val Γk:String = "test",
// Kotlin Bytecode: public final getName()Ljava/lang/String;valname:String = "test",
)
funmain() {
val jackson2Mapper = com.fasterxml.jackson.module.kotlin.jacksonObjectMapper()
val jackson2Json = jackson2Mapper.writeValueAsString(Foo())
println("Jackson 2: $jackson2Json")
val jackson3Mapper = tools.jackson.module.kotlin.jacksonMapperBuilder().build()
val jackson3Json = jackson3Mapper.writeValueAsString(Foo())
println("Jackson 3: $jackson3Json")
/* Output: Jackson 2: {"ΓΈx":"test","name":"test","ΓΈk":"test"} Jackson 3: {"Γk":"test","name":"test"}*/
}
When checking the Kotlin Bytecode, I see that fields starting with a non ASCII character does not get a uppercase letter in the getter. However, if the field starts with an uppercase non ASCII character, it gets a uppercase letter in the getter, and then the field is serialized with Jackson3.
This makes me think that the real issue is on the Kotlin side: Kotlin generates getΓΈx() instead of getΓx().
Should this be handled in jackson-module-kotlin instead, since the Kotlin compiler is the one generating the "non-standard" getter name?
@olesls Good point. Perhaps issue is indeed with Kotlin-side logic; and at least needs to be traced here first.
Looking at jackson-databindDefaultAccessorNamingStrategy.java I think it is checking for non-ASCII characters correctly, not limited to just ASCII.
So it does indeed sound like Kotlin is not recognizing non-ASCII leading character.
And if so, suggested work-around (allow leading lower-case letter) should work.
But ideally somehow Kotlin handling could be improved (but generation is not under Jackson's control so...).
I don't believe this is a bug, at least not in my opinion.
Both Kotlin and Jackson are functioning as designed.
If I had to guess, it might be considered a bug in Kotlin, but since it involves a change that affects the bytecode, it's highly unlikely to be fixed.
It seems that this is rarely an issue, and there are manual workarounds, so I don't currently intend to actively fix it as part of the kotlin-module.
Besides using JsonProperty or withFirstCharAcceptance, adding the JvmField annotation to the property also seems to work as a workaround.
I agree. It is more of a question about backwards compatibility. Given the workarounds, and the breaking changes mentioned here: https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#behavioral-changes, I think it makes sense to not fix this issue. But maybe it is worth mentioning it in the 'behavioral changes'-section, in case any more unlucky souls stumble upon it.
#1154: Due to changes in databind#2882 and Kotlin's bytecode generation specification, fields starting with lowercase non ASCII characters are silently dropped when serializing now.
Reacted by Ole Steinar LillestΓΈl Skrede and Tatu Saloranta
#1154: Due to changes in databind#2882 and Kotlin's bytecode generation specification, fields starting with lowercase non ASCII characters are silently ignored when serializing now.
Activity
cowtowncoder commentedon Apr 27, 2026
Likely due to FasterXML/jackson-databind#2882 which is mentioned in 3.0 Release notes (https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#behavioral-changes).
So, intentional change on Java side at least; not sure about Kotlin module -- but I think implementation should actually consider non-ASCII letters too.
Could you file a
jackson-databindissue for this one too? Apologies for extra work.NOTE: plain
@JsonPropertywould probably work as work-around, without needing to duplicate name.olesls commentedon Apr 28, 2026
Thanks! Just want to make sure I understand the issue here before filing an issue in
jackson-databind.Consider this example:
When checking the Kotlin Bytecode, I see that fields starting with a non ASCII character does not get a uppercase letter in the getter. However, if the field starts with an uppercase non ASCII character, it gets a uppercase letter in the getter, and then the field is serialized with Jackson3.
This makes me think that the real issue is on the Kotlin side: Kotlin generates
getΓΈx()instead ofgetΓx().Should this be handled in
jackson-module-kotlininstead, since the Kotlin compiler is the one generating the "non-standard" getter name?Using accessorNaming (from your link https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#behavioral-changes) is also a possible workaround.
.accessorNaming( DefaultAccessorNamingStrategy.Provider() .withFirstCharAcceptance(true, false), )cowtowncoder commentedon Apr 28, 2026
@olesls Good point. Perhaps issue is indeed with Kotlin-side logic; and at least needs to be traced here first.
Looking at
jackson-databindDefaultAccessorNamingStrategy.javaI think it is checking for non-ASCII characters correctly, not limited to just ASCII.So it does indeed sound like Kotlin is not recognizing non-ASCII leading character.
And if so, suggested work-around (allow leading lower-case letter) should work.
But ideally somehow Kotlin handling could be improved (but generation is not under Jackson's control so...).
k163377 commentedon May 2, 2026
I don't believe this is a bug, at least not in my opinion.
Both
KotlinandJacksonare functioning as designed.If I had to guess, it might be considered a bug in
Kotlin, but since it involves a change that affects the bytecode, it's highly unlikely to be fixed.It seems that this is rarely an issue, and there are manual workarounds, so I don't currently intend to actively fix it as part of the
kotlin-module.Besides using
JsonPropertyorwithFirstCharAcceptance, adding theJvmFieldannotation to the property also seems to work as a workaround.olesls commentedon May 4, 2026
I agree. It is more of a question about backwards compatibility. Given the workarounds, and the breaking changes mentioned here: https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#behavioral-changes, I think it makes sense to not fix this issue. But maybe it is worth mentioning it in the 'behavioral changes'-section, in case any more unlucky souls stumble upon it.
k163377 commentedon May 7, 2026
Since this is a
Kotlin-specific issue, would it be better to add it toChanges, JVM Languages?https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#kotlin
@cowtowncoder
I'm thinking of adding the following; what do you think?
cowtowncoder commentedon May 7, 2026
@k163377 Good idea! Maybe "dropped" -> "ignored" or "excluded"?
k163377 commentedon May 8, 2026
@cowtowncoder
Thank you.
I've adopted "ignored" and updated the wiki.
https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#kotlin
With the above update, this issue will be closed.
cowtowncoder commentedon May 8, 2026
@k163377 It would make sense to also mention this earlier in the Wiki:
https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#behavioral-changes
k163377 commentedon May 8, 2026
@cowtowncoder
Is this what you mean?
Behavioral changes
jackson-databind
...
Kotlin
cowtowncoder commentedon May 8, 2026
Yes. Although "Kotlin" -> "jackson-module-kotlin"
k163377 commentedon May 9, 2026
@cowtowncoder
Reflected.
https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0#jackson-module-kotlin