question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"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 issue

Ktor 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:closed
  • Created 3 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
nicchevacommented, Mar 23, 2020

The same code with ktor 1.3.0 produce:

kotlin.ClassCastException: kotlinx.serialization.json.JsonObject cannot be cast to io.ktor.client.call.HttpClientCall

But also works if accept and content type are same

1reaction
dmitrievanthonycommented, Mar 31, 2020

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 send application/vnd.any+json and assume it should be serialized also.

I would recommend you to fix it the following way:

            install(JsonFeature) {
                acceptContentTypes = listOf(
                    ContentType.parse("application/vnd.any.response+json"),
                    ContentType.parse("application/vnd.any+json")
                )
                serializer = KotlinxSerializer()
            }
Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found