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.