Kotlin Flow is one of the most powerful APIs in Kotlin Coroutines for managing asynchronous data streams. However, many developers encounter a common issue: Kotlin Flow not collecting. This problem can occur for several reasons, including incorrect usage of coroutine scopes, lifecycle mismanagement in Android, or misunderstanding how cold flows behave. In this article, we will deeply explore the reasons behind this issue and provide practical solutions with complete code examples.

Understanding Kotlin Flow
Before we troubleshoot why Kotlin Flow is not collecting, it’s essential to understand the basic behavior of Flow. A Flow in Kotlin is cold, meaning it does not start emitting values until it is collected. If you forget to call .collect()
, nothing happens. For example:
val numberFlow = flow { for (i in 1..5) { emit(i) } } // Nothing happens yet, because no one is collecting the flow
If you don’t collect this flow, you will not see any result. Once you add collect()
, values are emitted:
CoroutineScope(Dispatchers.Main).launch { numberFlow.collect { value -> println("Collected: $value") } }
This shows the first and most important rule: Flows must be collected to trigger emission.
Common Reasons Kotlin Flow is Not Collecting
Issue | Description | Solution |
---|---|---|
No Collector | Flow is defined but never collected | Add .collect() in a coroutine scope |
Wrong Coroutine Scope | Collecting flow in a scope that is cancelled too early | Use a proper scope like lifecycleScope in Android |
Cold Flow Misunderstanding | Expecting Flow to emit automatically without collection | Always remember Flow is cold until collected |
Lifecycle Issue | In Android, collection stops when Activity/Fragment is destroyed | Use repeatOnLifecycle to restart collection |
Dispatcher Problem | Flow emits on background but UI is not updated | Use flowOn and collect on Main thread if needed |
Example Case: Flow Not Collecting in Android
Consider the following scenario in Android where a developer sets up a Flow inside a ViewModel but the UI never updates:
// ViewModel class MainViewModel : ViewModel() { private val _numbers = MutableStateFlow(0) val numbers: StateFlow<Int> = _numbers fun startEmitting() { viewModelScope.launch { for (i in 1..5) { delay(1000) _numbers.value = i } } } }
// Activity or Fragment class MainActivity : AppCompatActivity() { private val viewModel: MainViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewModel.startEmitting() // ❌ Wrong collection, will not update after onCreate lifecycleScope.launch { viewModel.numbers.collect { value -> println("Collected: $value") } } } }
The above code looks correct, but if the Activity is paused and resumed, the collection might stop. The recommended approach is to use repeatOnLifecycle
so that the Flow re-collects whenever the lifecycle is active:
// ✅ Correct way using repeatOnLifecycle lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.numbers.collect { value -> println("Collected: $value") } } }
Using collectLatest
Another common mistake is when developers expect only the latest value but still use collect()
. In such cases, you may want to use collectLatest()
, which cancels the previous collector block when a new value is emitted:
lifecycleScope.launch { viewModel.numbers.collectLatest { value -> println("Latest: $value") } }
Troubleshooting Checklist
- ✅ Did you call
.collect()
on your Flow? - ✅ Are you collecting in the correct CoroutineScope?
- ✅ If in Android, are you using
repeatOnLifecycle
? - ✅ Are you switching the correct dispatcher with
flowOn
? - ✅ Did you use
collectLatest()
if only the latest value matters?
Conclusion
When you face the issue of Kotlin Flow not collecting, the root cause usually lies in either not calling .collect()
, using the wrong coroutine scope, or mishandling Android lifecycle events. By carefully applying the right collection method, ensuring the correct scope, and handling lifecycle-aware collection with repeatOnLifecycle
, you can make your flows work seamlessly. Always remember: a Flow is cold until collected.
For further reading on Kotlin Flow best practices, you can check the official documentation at Android Kotlin Flow documentation.