Run Blocking In Coroutine
ID |
kotlin.run_blocking_in_coroutine |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Kotlin |
Tags |
concurrency, reliability |
Description
Reports calls to runBlocking { … } made from inside another coroutine
builder (launch, async, withContext, coroutineScope,
supervisorScope, flow, channelFlow, produce, …).
Rationale
scope.launch {
runBlocking { delay(100) } // FLAW
}
runBlocking parks the OS thread until its child coroutine completes. Inside
another coroutine builder, that thread belongs to the parent’s dispatcher
pool — typically a small, shared pool. If the child coroutine needs a thread
from the same pool to make progress, the runBlocking deadlocks the whole
pool. This is a classic footgun on the Default and IO dispatchers.