Closed Tlaster closed 2 years ago
Hi @Tlaster , which Ktor version are you using?
I'm using Version 2.0.1.
And I also notice that when trying the workload in the repo, I can reproduce the error by adding @Headers(value = ["Content-Type: application/json"])
to JsonPlaceHolderApi.getPosts()
. (I run it by ./gradlew :workload:runDebugExecutableLinuxX64
)
Just got the same error when using @FormUrlEncoded annotation
2022-06-01 11:44:14.088 3743-3815/ua.blink E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-6
Process: ua.blink, PID: 3743
io.ktor.http.UnsafeHeaderException: Header(s) [Content-Type] are controlled by the engine and cannot be set explicitly
at io.ktor.client.engine.HttpClientEngineKt.validateHeaders(HttpClientEngine.kt:158)
at io.ktor.client.engine.HttpClientEngineKt.access$validateHeaders(HttpClientEngine.kt:1)
at io.ktor.client.engine.HttpClientEngine$install$1.invokeSuspend(HttpClientEngine.kt:65)
at io.ktor.client.engine.HttpClientEngine$install$1.invoke(HttpClientEngine.kt)
at io.ktor.client.engine.HttpClientEngine$install$1.invoke(HttpClientEngine.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:91)
at io.ktor.client.plugins.logging.Logging$setupRequestLogging$1.invokeSuspend(Logging.kt:74)
at io.ktor.client.plugins.logging.Logging$setupRequestLogging$1.invoke(Logging.kt)
at io.ktor.client.plugins.logging.Logging$setupRequestLogging$1.invoke(Logging.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:101)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.client.plugins.HttpSend$DefaultSender.execute(HttpSend.kt:135)
at io.ktor.client.plugins.auth.Auth$Plugin$install$2.invokeSuspend(Auth.kt:44)
at io.ktor.client.plugins.auth.Auth$Plugin$install$2.invoke(Auth.kt)
at io.ktor.client.plugins.auth.Auth$Plugin$install$2.invoke(Auth.kt)
at io.ktor.client.plugins.HttpSend$InterceptedSender.execute(HttpSend.kt:113)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invokeSuspend(HttpRedirect.kt:61)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invoke(HttpRedirect.kt)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invoke(HttpRedirect.kt)
at io.ktor.client.plugins.HttpSend$InterceptedSender.execute(HttpSend.kt:113)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invokeSuspend(HttpCallValidator.kt:149)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpSend$InterceptedSender.execute(HttpSend.kt:113)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invokeSuspend(HttpSend.kt:101)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invoke(HttpSend.kt)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invoke(HttpSend.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:91)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invokeSuspend(HttpCallValidator.kt:125)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invoke(HttpCallValidator.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invokeSuspend(HttpRequestLifecycle.kt:35)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invoke(HttpRequestLifecycle.kt)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invoke(HttpRequestLifecycle.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:101)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
@Tlaster have you been able to overcome this issue yet?
@Tlaster have you been able to overcome this issue yet?
No, our team end up creating a new one that just generates ktor call without any runtime: https://github.com/qdsfdhvh/ktor-fit
Hi @Tlaster , @gazanfarov
i released a new version ( v1.0.0-beta07). I removed the Content-Type Header, so the error is not fix for now. I still dont understand why Ktor doesn
t allow this header
@Foso just noticed new commit and here you are. God speed! 🤓 Going to check it today, thank you!
Update: everything works now.
Describe the bug When using
@FormUrlEncoded
, ktor will throw an errorio.ktor.http.UnsafeHeaderException: Header(s) [Content-Type] are controlled by the engine and cannot be set explicitly
, I think it's a limitation from ktor since there's already an issue about it. But I haven't got a solution yet.To Reproduce Steps to reproduce the behavior: Make an api interface with
@FormUrlEncoded
Expected behavior We can make
@FormUrlEncoded
requestSoftware used