kotlin-coroutines-structured-concurrency

Detects and fixes Kotlin coroutine anti-patterns like stored scopes, init launches, and swallowed cancellation.

Updated May 21, 2025
One-click install
npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill kotlin-coroutines-structured-concurrency-albertmartorell1975
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: kotlin-coroutines-structured-concurrency
Source: https://github.com/albertmartorell1975/MeteoMartoCompose/tree/main/.agents/skills/kotlin-coroutines-structured-concurrency
Command: npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill kotlin-coroutines-structured-concurrency-albertmartorell1975

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Kotlin codebases often accumulate dangerous coroutine anti-patterns: classes storing CoroutineScope as properties, init blocks launching fire-and-forget work, runBlocking bridging suspend APIs, and catch blocks silently swallowing CancellationException. These bugs cause silent work loss, uncancellable background loops, and broken structured concurrency that are extremely hard to diagnose in production. ## Core Features & Use Cases - Anti-pattern Detection: Identifies stored CoroutineScope properties, init-block launches, fire-and-forget public APIs on repositories and managers, DI-bound singletons launching from constructors, and Initializer classes that launch instead of register. - Cancellation Safety Review: Catches runCatching and broad catch (Exception/Throwable) blocks around suspend calls that swallow CancellationException, with concrete fix patterns like ensureActive() and conditional rethrow. - runBlocking Remediation: Flags runBlocking in suspend-capable code and tests (recommending runTest), while documenting legitimate carve-outs like ContentProvider members. - Use Case: During code review of an Android repository class with private val scope: CoroutineScope and fun refresh() { scope.launch { ... } }, apply this Skill to refactor it into a clean suspend fun refresh() API where the ViewModel's viewModelScope owns the lifecycle. ## Quick Start Review this Kotlin repository class for coroutine structured-concurrency violations and refactor any stored scopes or fire-and-forget launches into suspend APIs.

Frequently Asked Questions about kotlin-coroutines-structured-concurrency

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I fix a Kotlin class that stores CoroutineScope as a property?▼

Remove the stored CoroutineScope and convert the public functions to suspend functions so the caller owns the scope. The caller, typically a ViewModel using viewModelScope, then decides the lifecycle, error handling, and cancellation semantics.

Why is launching a coroutine from an init block dangerous?▼

An init-block launch is a construction-time side effect the caller cannot await, cancel, or observe for errors. If the scope is later cancelled, subsequent launches silently complete as cancelled with no exception or log, making the failure nearly invisible.

When is it acceptable to use viewModelScope.launch in Android?▼

It is acceptable only in UI state holders like ViewModels that absorb non-suspending UI events such as onClick callbacks. The scope must be lifecycle-bound like viewModelScope, and the layers underneath should still expose suspend APIs.

Should I use runBlocking or runTest in Kotlin coroutine tests?▼

Use runTest in tests because it provides virtual time so delay returns immediately, integrates with TestDispatcher, and ensures proper coroutine cleanup. runBlocking runs in real time, making tests slow and flaky.

Why does catching Exception around a suspend call break cancellation?▼

A broad catch on Exception or Throwable also matches CancellationException, so the parent coroutine believes the child finished normally while cancellation is silently ignored. Fix it by rethrowing CancellationException first or calling currentCoroutineContext().ensureActive().

When is runBlocking acceptable in Android code?▼

runBlocking is acceptable only at genuine synchronous boundaries such as ContentProvider member functions like query or insert, CLI main functions, or Java interop shims. Keep the blocking body minimal and call suspending code immediately.