Retrofit 2.6.0 exception: java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.Deferred

Reading https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-260-2019-06-05 I saw:

New: Support suspend modifier on functions for Kotlin! This allows you to express the asynchrony of HTTP requests in an idiomatic fashion for the language.

@GET("users/{id}") suspend fun user(@Path("id") long id): User

Behind the scenes this behaves as if defined as fun user(...): Call and then invoked with Call.enqueue. You can also return Response for access to the response metadata.

Currently this integration only supports non-null response body types. Follow issue 3075 for nullable type support.

I changed requests so: added suspend and removed Deferred:

@FormUrlEncoded
@POST("user/info/")
suspend fun getUserInfo(@Field("token") token: String): UserInfoResponse


override suspend fun getUserInfo(token: String): UserInfoResponse =
    service.getUserInfo(token)

Then in interactor (or simply when called the method getUserInfo(token)) removed await():

override suspend fun getUserInfo(token: String): UserInfoResponse =
    // api.getUserInfo(token).await() - was before.
    api.getUserInfo(token)

UPDATE

Once I encountered a situation when downloading PDF files required removing suspend in Api class. See How to download PDF file with Retrofit and Kotlin coroutines?.


In my case I was missing the CoroutineCallAdapterFactory in my Retrofit initialization. Retrofit v2.5.0

Before:

val retrofit = Retrofit.Builder()
                .baseUrl(BuildConfig.BASE_URL)
                .client(httpClient)
                .addConverterFactory(MoshiConverterFactory.create())
                .build()

After: (working code)

val retrofit = Retrofit.Builder()
                .baseUrl(BuildConfig.BASE_URL)
                .client(httpClient)
                .addConverterFactory(MoshiConverterFactory.create())
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .build()