Unreachable code can be safely removedKT-W1065The property can be declared as `const`KT-P1001Iterator implementation does not throw `NoSuchElementException`KT-W1033Unreachable catch blocks must be removedKT-W1064Avoid using `forEach` with rangesKT-P1000Non-compliant class/object name detectedKT-C1000Checked cast can be replaced with a safe castKT-E1004Catch block should not require to check or cast the type of exception via `is` or `as`KT-W1000The range specified for iteration is emptyKT-W1031Calling `hasNext()` on an `Iterator` should not have any side-effectsKT-W1032Declaration of `serialVersionUID` not foundKT-W1060The class overrides `equals` but not `hashCode`KT-W1028`null` comparison using `equals` methodKT-W1049Map values fetched with not-null assertion operatorKT-W1034Non-compliant enum variant name detectedKT-C1001Exceptions should not be rethrown after being wrapped in a new instance of the same typeKT-W1008Avoid explicitly triggering garbage collectionKT-W1029Avoid using `GlobalScope` to launch coroutinesKT-E1001Avoid casting to nullable types using `as`KT-E1002`equals` should be overridden correctlyKT-E1003Proper logging should be preferred over printing stack trace of exceptionsKT-W1002Caught exceptions must not be rethrownKT-W1003Ensure exceptions that are caught are actually handledKT-W1005Avoid catching overly generic exceptionsKT-W1009`equals` method always returns the same resultKT-W1027Loop with unconditional jump statementsKT-W1035File location does not match the declared packageKT-W1044Found shadowed variable declarationKT-W1045Found usages of `lateinit` modifierKT-W1047Method should not throw exceptionsKT-W1056Don't throw `IllegalArgumentException` manually, use `require()` insteadKT-W1057The class can be declared as a data classKT-W1058Unused parameters should be removedKT-W1061Avoid casting nullable types to non-null typesKT-E1006Avoid casting immutable collection types to mutable collection typesKT-E1007Avoid not-null assertions with `!!`KT-E1010Inner class can be a static nested classKT-R1001Variables that can be non-nullable should not be marked as nullableKT-W1070Found type cast that will never succeedKT-E1011Blocking operations should be avoided in coroutinesKT-E1012Redundant `filter()` calls should be removedKT-W1073Abstract class should be refactored into either an interface or concrete classKT-R1000Avoid suspend function calls in `runCatching`KT-W1066Function must not return from a `finally` blockKT-W1069Prefer usage of `Unit` over `Void`KT-W1071Redundant `map()` calls should be removedKT-W1072Extensive `let` usage should be replaced with ordinary method or extension function callKT-W1074Functions with only the `return` statement should be rewritten with expression body syntaxKT-W1051Found `if` statements that can be collapsed into oneKT-W1048Unnecessary `abstract` modifier in interface detectedKT-W1054Found function that only returns a constantKT-W1052Redundant use of `?.` detectedKT-W1063Found duplicate condition in binary expressionKT-W1043Detected member with `protected` visibility in `final` classKT-W1055Multiple occurrences of the same string literal within a single file detectedKT-W1042Declaring lambda parameters as `it` is redundantKT-W1050Array literals must be used instead of `arrayOf()`KT-W1059Return values must not be ignoredKT-E1008Explicit `public` modifiers on nested classes have no effectKT-W1053Redundant use of `!!` detectedKT-W1062Avoid referential equality test for stringsKT-E1005Prefer `to` over `Pair` syntaxKT-C1002`toString()` must not be called on a nullable objectKT-E1009Detected `?: emptyList()` that can be replaced with `orEmpty()` callKT-R1004Detected `require` calls for not-null check that can be replaced with `requireNotNull`KT-R1005Functions that return a Flow instance should not be marked as `suspend`KT-W1068Detected `isEmpty` or `isBlank` calls to assign a default valueKT-R1002Detected null or empty check that can be replaced with `isNullOrEmpty()`KT-R1003Functions that have `CoroutineScope` as receiver should not be marked as `suspend`KT-W1067Ensure all APIs are implementedKT-W1001Avoid throwing exceptions within `finally` blocksKT-W1010Method should not return from finally blocksKT-W1004The main method should not throw exceptionsKT-W1007The result of increment/decrement operation is unusedKT-W1036Array constructors should be preferred over the spread operatorKT-P1004Creation of temporary objects when converting primitive types to `String`KT-P1002Detected the use of forbidden commentsKT-D1000Having empty blocks in the code is redundantKT-W1012Implicit default locale used for string processingKT-W1030Function with cyclomatic complexity higher than threshold foundKT-R1006Specialized primitive array classes should be preferred over `Array<Primitive>`KT-P1003
Kotlin logoKotlin/
KT-E1001

Avoid using `GlobalScope` to launch coroutinesKT-E1001

Major severityMajor
Bug Risk categoryBug Risk

The use of GlobalScope.launch or GlobalScope.async was detected. The use of GlobalScope is discouraged according to Kotlin' official documentation.

GlobalScope is marked with the @DelicateCoroutinesApi annotation, signifying that using it could cause problems such as resource or memory leaks if used incorrectly.

The Kotlin documentation states that the GlobalScope instance is used to launch top-level coroutines that operate on the whole application's lifetime.

Since such coroutines will operate over the lifetime of the entire program, they are not subject to the restrictions of any framework-specific state, such as that of DI components or Android view scopes.

If you use GlobalScope to launch an operation that should have been confined to a smaller lifetime, such as that of a request handler or a fragment, it is possible to allow a resource to stay in memory for longer than the lifetime of its originating scope. In other words, memory or resources will be leaked.

Bad Practice

fun foo() {
    GlobalScope.launch { delay(1_000L) }
}

Remove usages of GlobalScope.launch and GlobalScope.async from your codebase.

There are various approaches you can take instead:

  1. If you are using non-coroutine code and want to start using coroutines, use runBlocking to create a local coroutine scope and keep all async operations within that runBlocking call.

    Note that runBlocking should be used sparingly, and you should only call it at the top of the coroutine hierarchy, and never within other coroutines.

  2. In frameworks like Spring, coroutine scope creation is handled for you already, and if you need to create new scopes, you just need to use coroutineScope to create a new local scope that will end when you finish handling a request, or whatever other operation you are performing.
  3. For Android, use viewModelScope if you are within a ViewModel, or lifecycleScope if you are within an activity/fragment.
fun foo() {
    // defined elsewhere
    localScope.launch { delay(1_000L) }
}

fun onDestroy() {
    localScope.cancel()
}

References