Must be called during a transaction (CouchbaseLite Android v3.1.0-425@33 (EE/release, Commit/3f009a25f8@934af6e32f2a Core/3.1.0 (356) at 2023-04-14T04:06:14.503123Z) on Java; Android 12; SM-T500)

Sometimes we are facing this issue, as it gets triggered during the data-saving process into the database, but the data is not being saved. We encounter the following error:

Note: We are unable to catch the error all the time, but errors are being recorded in production, and data is not being saved.

Couchbase version: “com.couchbase.lite:couchbase-lite-android-ee:3.1.0”

Error: “must be called during a transaction”
(CouchbaseLite Android v3.1.0-425@33 (EE/release, Commit/3f009a25f8@934af6e32f2a Core/3.1.0 (356) at 2023-04-14T04:06:14.503123Z) on Java; Android 12; SM-T500)

return withContext(backgroundDispatcher) {

        val queryResult = kotlin.runCatching {

            val map = converter.toMap(model).toMutableMap().apply {
            val document = MutableDocument(id, map)
            ) { newDoc, curDoc ->
                if (curDoc == null) {
                    // No existing document, treat it as creation
                } else {
                    val resolvedDoc = MutableDocument(

                    // Remove the _id key from newDoc before merging
                    val newDataMap: MutableMap<String, Any> = newDoc.toMap().toMutableMap()

                    // Merge the data from newDoc and curDoc

                    val mergedDataMap: MutableMap<String, Any> = mutableMapOf()


            ?.let { docId -> getDocument(docId) }
            ?: {
                val error =queryResult.exceptionOrNull()!!
                Log.d("Error Save/Update",error.toString())

Please help us to fix the error

I realize that it may be difficult but I am going to need a stack trace to have any chance of addressing this.

Thanks for the reply but we are not able to get this in development as i told, we are able to see logs in production, please find the logs below,

QueryResultError -StackTrace : CouchbaseLiteException{CouchbaseLite,17,‘must be called during a transaction
(CouchbaseLite Android v3.1.0-425@33 (EE/release, Commit/3f009a25f8@934af6e32f2a Core/3.1.0 (356) at 2023-04-14T04:06:14.503123Z) on Java; Android 13; SM-T575)’}
at com.couchbase.lite.Collection.saveInTransaction(
at com.couchbase.lite.Collection.saveLocked(
at com.couchbase.lite.Collection.saveWithConflictHandler(
at$saveUserSession$$inlined$saveDocument$1.invoke(Unknown Source:8)
at$saveUserSession$$inlined$saveDocument$1.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:166)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at xxxx.xxxxxxxx.xxxxx.features.session.ForegroundBackgroundListener.createNewAppSession$addAppSessionToUserSession(ForegroundBackgroundListener.kt:123)
at xxxx.xxxxxxxx.xxxxx.features.session.ForegroundBackgroundListener.access$createNewAppSession$addAppSessionToUserSession(ForegroundBackgroundListener.kt:21)
at xxxx.xxxxxxxx.xxxxx.features.session.ForegroundBackgroundListener$createNewAppSession$1.invokeSuspend(ForegroundBackgroundListener.kt:145)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$
Caused by: LiteCoreException{1, 17, “must be called during a transaction”}
at com.couchbase.lite.internal.core.C4Document.createFromSlice(Native Method)
at com.couchbase.lite.internal.core.C4Document.create(
at com.couchbase.lite.internal.core.C4Collection.createDocument(
at com.couchbase.lite.Collection.createC4Document(
at com.couchbase.lite.Collection.saveInTransaction(
… 22 more

I’m not entirely sure what is going on, here: I haven’t had time, yet, to examine it in detail. Looking at the code, I would say that it is impossible.

Here is the code that is producing the error:

        try {
            try {
                saveInTransaction(document, (baseDoc == null) ? null : baseDoc.getC4doc(), deleting);
                commit = true;
            catch (CouchbaseLiteException e) {
                if (!CouchbaseLiteException.isConflict(e)) { throw e; }

The call to saveInTransaction cannot be reached except within a transaction, in the normal execution of this code.

I’m going to wildly point an accusing finger at Kotlin coroutines.

I have opened ticket CBL-4978 to track this issue.

Is there any chance you can show me the code for the method:$saveUserSession

It would be a huge help.

Also of considerable help would be logs from around the time this error takes place.

FWIW, I cannot find any way to attribute this to an issue with the use of Kotlin Coroutines.

We are just sending the pojo to above model

override suspend fun saveUserSession(userSession: UserSession): Boolean {
return DatabseModelQuery.from(heelper)
.getOrNull() != null

If the database becomes locked, will we encounter this issue?

I’m not exactly sure of what you mean when you say “if the database becomes locked”.

Here’s what I can say: Database use is, essentially, single threaded. Nearly every call to a method that uses the database will seize a lock that prevents any other access until the first call completes. It is possible to do some concurrent processing by opening two different instances of the same database… but even then, file access is single threaded: a long running query, for instance, will block all other access until it completes.

Can you tell me which of the methods in saveUserSession are suspend methods?

As I say, if you can share logs that would be tremendously helpful.

@blake.meike saveDocument(userSession) is the one is suspend function, As I told earlier we didn’t faced this in development environment, If I get it will post it immediately.