"kotlin.IllegalStateException: Fail to send body. Content has type: class kotlinx.serialization.json.JsonObject, but OutgoingContent expected." when acceptContentTypes and contentType are differents
See original GitHub issueKtor Version and Engine Used (client or server and name) 1.3.2, client Curl or IOS
Describe the bug IllegalStateException is thrown when acceptContentTypes and contentType are different. When both are same, the client call is ok and http response is correct.
To Reproduce Steps to reproduce the behavior:
@Serializable
data class User(
val email: String,
val password: String
)
@UnstableDefault
@KtorExperimentalAPI
class Sample {
val client: HttpClient by lazy {
HttpClient(Curl.create()) {
expectSuccess = false
install(JsonFeature) {
acceptContentTypes = listOf(
ContentType.parse("application/vnd.any.response+json")
)
serializer = KotlinxSerializer()
}
}
}
}
@ImplicitReflectionSerializer
@KtorExperimentalAPI
@UnstableDefault
fun main() = runBlocking {
val response: HttpResponse = Sample().client.put {
url("https://httpbin.org/put")
contentType(
ContentType.parse("application/vnd.any+json")
)
body = Json(JsonConfiguration.Stable).toJson(User("mail@mail.com", "password1234"))
}
println(response.readText())
}
Uncaught Kotlin exception: kotlin.IllegalStateException: Fail to send body. Content has type: class kotlinx.serialization.json.JsonObject, but OutgoingContent expected.
at 0 untitled.kexe 0x00000001002e6317 kfun:kotlin.Throwable.<init>(kotlin.String?)kotlin.Throwable + 87 (/Users/teamcity3/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Throwable.kt:22:37)
at 1 untitled.kexe 0x00000001002df5d5 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 85 (/Users/teamcity3/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:44)
at 2 untitled.kexe 0x00000001002df775 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 85 (/Users/teamcity3/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:44)
at 3 untitled.kexe 0x00000001002dfc35 kfun:kotlin.IllegalStateException.<init>(kotlin.String?)kotlin.IllegalStateException + 85 (/Users/teamcity3/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/Exceptions.kt:70:44)
at 4 untitled.kexe 0x00000001005d0206 kfun:io.ktor.client.features.HttpSend.Feature.$install$lambda-0COROUTINE$26.invokeSuspend#internal + 5270 (/Users/teamcity3/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/kotlin/util/Preconditions.kt:98:15)
at 5 untitled.kexe 0x00000001005d0728 kfun:io.ktor.client.features.HttpSend.Feature.$install$lambda-0COROUTINE$26.invoke#internal + 312 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/features/HttpSend.kt:72:71)
at 6 untitled.kexe 0x0000000100549d22 kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal + 1122 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt:207:0)
at 7 untitled.kexe 0x000000010054937b kfun:io.ktor.util.pipeline.SuspendFunctionGun.proceed#internal + 395 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt:18:0)
at 8 untitled.kexe 0x00000001005ccdec kfun:io.ktor.client.features.HttpRequestLifecycle.Feature.$install$lambda-0COROUTINE$25.invokeSuspend#internal + 1212 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/features/HttpRequestLifecycle.kt:34:21)
at 9 untitled.kexe 0x00000001005cd508 kfun:io.ktor.client.features.HttpRequestLifecycle.Feature.$install$lambda-0COROUTINE$25.invoke#internal + 312 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/features/HttpRequestLifecycle.kt:28:73)
at 10 untitled.kexe 0x0000000100549d22 kfun:io.ktor.util.pipeline.SuspendFunctionGun.loop#internal + 1122 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt:207:0)
at 11 untitled.kexe 0x000000010054937b kfun:io.ktor.util.pipeline.SuspendFunctionGun.proceed#internal + 395 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt:18:0)
at 12 untitled.kexe 0x00000001005497da kfun:io.ktor.util.pipeline.SuspendFunctionGun.execute#internal + 474 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/PipelineContext.kt:183:16)
at 13 untitled.kexe 0x0000000100543909 kfun:io.ktor.util.pipeline.Pipeline.execute(TContext;TSubject)TSubject + 361 (/opt/buildAgent/work/a85294440dc5c6e/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt:27:41)
at 14 untitled.kexe 0x00000001005a44ed kfun:io.ktor.client.HttpClient.$executeCOROUTINE$0.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? + 653 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt:164:25)
at 15 untitled.kexe 0x00000001005a4834 kfun:io.ktor.client.HttpClient.execute(io.ktor.client.request.HttpRequestBuilder)io.ktor.client.call.HttpClientCall + 308 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt:163:13)
at 16 untitled.kexe 0x00000001005e0c0f kfun:io.ktor.client.statement.HttpStatement.$executeUnsafeCOROUTINE$96.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? + 943 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:104:27)
at 17 untitled.kexe 0x00000001005e0f1b kfun:io.ktor.client.statement.HttpStatement.executeUnsafe$ktor-client-core()io.ktor.client.statement.HttpResponse + 235 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:101:22)
at 18 untitled.kexe 0x00000001005dfbbb kfun:io.ktor.client.statement.HttpStatement.$executeCOROUTINE$93.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? + 1259 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:43:38)
at 19 untitled.kexe 0x00000001005e0584 kfun:io.ktor.client.statement.HttpStatement.execute(kotlin.coroutines.SuspendFunction1<io.ktor.client.statement.HttpResponse,T>){0<kotlin.Any?>}Generic + 308 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:42:13)
at 20 untitled.kexe 0x00000001005e06f4 kfun:io.ktor.client.statement.HttpStatement.execute()io.ktor.client.statement.HttpResponse + 228 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:58:43)
at 21 untitled.kexe 0x000000010028c905 kfun:sample.$main$lambda-0COROUTINE$0.invokeSuspend#internal + 6117 (/opt/buildAgent/work/a85294440dc5c6e/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt:71:32)
at 22 untitled.kexe 0x00000001003068dc kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) + 700 (/Users/teamcity3/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt:26:0)
at 23 untitled.kexe 0x0000000100467d0a kfun:kotlinx.coroutines.DispatchedTask.run() + 2570 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt:42:0)
at 24 untitled.kexe 0x000000010044241d kfun:kotlinx.coroutines.EventLoopImplBase.processNextEvent()kotlin.Long + 813 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/EventLoop.common.kt:272:20)
at 25 untitled.kexe 0x00000001004748f8 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 1864 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:65:44)
at 26 untitled.kexe 0x0000000100473aaf kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,T>){0<kotlin.Any?>}Generic + 1231 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:50:22)
at 27 untitled.kexe 0x0000000100473fca kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,T>;kotlin.Int){0<kotlin.Any?>}Generic + 330 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:33:8)
at 28 untitled.kexe 0x000000010028aff2 kfun:sample.main() + 162 (/Users/niccheva/code/kotlin/untitled/src/macosMain/kotlin/sample/SampleMacos.kt:47:14)
at 29 untitled.kexe 0x000000010028e06a Konan_start + 138 (/Users/niccheva/code/kotlin/untitled/src/macosMain/kotlin/sample/SampleMacos.kt:47:1)
Expected behavior Expected client call to works when accept and content type are different.
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (5 by maintainers)
Top Results From Across the Web
Fail to serialize body. Content has type: class java.util ...
IllegalStateException : Fail to serialize body. Content has type: class java.util.Collections$SingletonList, but OutgoingContent expected.
Read more >Unable to set the Content-Type header in a request : KTOR-620
I'm accessing and API that requires me to set Content-Type for all requests, but I'm getting io.ktor.http.UnsafeHeaderException: Header Content-Type is ...
Read more >WhatsNew 1.3 | Ktor Framework
IllegalStateException : Fail to send body. Content has type: class kotlinx.serialization.json.JsonObject, but OutgoingContent expected.
Read more >transformers ImportError: cannot import name ... - GitAnswer
I installed the latest transformers 3.0.2 (both from pip and souce) and I have an error that I can not import BERTPRETRAINEDMODELARCHIVEMAP.
Read more >Untitled
"kotlin.IllegalStateException: Fail to send body. Content has type: class kotlinx.serialization.json.JsonObject, but OutgoingContent expected.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The same code with ktor 1.3.0 produce:
But also works if accept and content type are same
Well, that’s the truth. I confused about everything. I spent some time investigating the JsonFeature code and realized that
acceptedContentTypes
there should contain all content types (received and sent) that should be serialized.In your example, you mention in the feature that it should work only with
application/vnd.any.response+json
, but at the same time you sendapplication/vnd.any+json
and assume it should be serialized also.I would recommend you to fix it the following way: