Deferred Result Unused
ID |
kotlin.deferred_result_unused |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Kotlin |
Tags |
concurrency, reliability, unused-code |
Description
Reports async { … } calls whose Deferred<T> result is dropped — no
assignment, no await(), no return.
Rationale
suspend fun bad() = coroutineScope {
async { compute() } // FLAW — result discarded
println("done")
}
async launches a coroutine and returns a Deferred carrying the value to
be produced. When that handle is discarded, the work still runs but the
caller never sees the result, and any exception raised inside the coroutine
is swallowed (often surprisingly cancelling the parent scope). The most
common cause is treating async as fire-and-forget when launch is what
the caller actually wants.
Remediation
suspend fun good() = coroutineScope {
val d = async { compute() }
println(d.await())
}
// or, for fire-and-forget
scope.launch { compute() }
Capture the Deferred and await() it, or use launch { } when the result
is genuinely not needed.