Compatibility guide for Kotlin 2.4.x Keeping the Language Modern and Comfortable Updates are among the fundamental principles in Kotlin Language Design. The former says that constructs which obstruct language evolution should be removed, and the latter says that this removal should be well-communicated beforehand to make code migration as smooth as possible.
While most of the language changes were already announced through other channels, like update changelogs or compiler warnings, this document summarizes them all, providing a complete reference for migration from Kotlin 2.3 to Kotlin 2.4. This document also includes information about tool-related changes.
Basic terms In this document, we introduce several kinds of compatibility:
source : source-incompatible change stops code that used to compile fine (without errors or warnings) from compiling anymore
binary : two binary artifacts are said to be binary-compatible if interchanging them doesn't lead to loading or linkage errors
behavioral : a change is said to be behavioral-incompatible if the same program demonstrates different behavior before and after applying the change
Remember that those definitions are given only for pure Kotlin. Compatibility of Kotlin code from the other languages perspective (for example, from Java) is out of the scope of this document.
Language Drop support for -language-version=1.9 and the K1 compiler Issue : KT-80590
Component : Compiler
Incompatible change type : source
Short summary : Starting with Kotlin 2.4, the compiler no longer supports -language-version=1.9 . As a result, the K1 compiler is no longer supported.
Deprecation cycle :
Prohibit flexible explicit nullable type arguments for Java types Issue : KTLC-284
Component : Core language
Incompatible change type : source
Short summary : Previously, when calling Java APIs from Kotlin, the compiler could treat explicitly specified nullable type arguments as flexible type arguments. Kotlin 2.4.0 no longer applies this behavior for nullable type arguments, so the compiler now reports errors for code that could break type safety or fail at runtime.
Deprecation cycle :
Prohibit always-false is checks for definitely incompatible types Issue : KTLC-365
Component : Core language
Incompatible change type : source
Short summary : The compiler now prevents meaningless is checks that are always false because the checked types are definitely incompatible. This keeps the behavior consistent with other operations involving incompatible types.
Deprecation cycle :
Prohibit exposing types and declarations with lower visibility in inline functions Issue : KTLC-283
Component : Core language
Incompatible change type : source
Short summary : The compiler now prevents inline functions from exposing types and declarations that have lower visibility than the inline function itself.
Deprecation cycle :
Change default use-site target selection for annotations Issue : KTLC-391
Component : Core language
Incompatible change type : binary
Short summary : Kotlin 2.4.0 updates the defaulting rules for propagating annotations to parameters, properties, and fields. This can affect annotation processing, reflection, and binary metadata after recompilation. When you don't specify a use-site target, the compiler now uses param and property if they apply, and uses field only if property doesn't apply.
You can specify a use-site target explicitly, such as @param:Annotation instead of @Annotation. To use the previous defaulting rule for your whole project, add -Xannotation-default-target=first-only to your build file.
Deprecation cycle :
Forbid implicit references to inaccessible types Issue : KTLC-384
Component : Core language
Incompatible change type : source
Short summary : Using declarations that implicitly reference inaccessible types from indirect dependencies now results in an error.
To migrate, add an explicit dependency on the module that declares the inaccessible type, or update the intermediate API so it doesn't expose that type.
Deprecation cycle :
Enforce Jakarta nullability annotations Issue : KTLC-285
Component : Core language
Incompatible change type : source
Short summary : The compiler now enforces declared nullability in Kotlin for Java declarations that use jakarta.annotation.Nullable or jakarta.annotation.Nonnull . If you assign a Java declaration marked as nullable by these annotations to a non-null Kotlin type, the compiler reports an error.
Deprecation cycle :
Report misplaced type arguments in callable reference qualifiers Issue : KTLC-388
Component : Core language
Incompatible change type : source
Short summary : The compiler now checks the left-hand side of callable references and reports a warning if an inner class contains type arguments in the wrong part of the qualifier.
To migrate, update the reference so that each type argument belongs to the class that declares it. For example, write the full type Outer<Int>.Inner<String>::toString instead of Inner<String, Int>::toString.
Deprecation cycle :
Report errors for class literals from reified type parameters with nullable upper bounds Issue : KTLC-370
Component : Core language
Incompatible change type : source
Short summary : The compiler now reports an error when you use ::class on an expression whose type comes from a reified type parameter with a nullable upper bound. If you use ::class on such an expression, make the value non-null first with an explicit null check or the !! operator.
Deprecation cycle :
Prohibit initialization before declarations in anonymous objects Issue : KTLC-290
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an error when you initialize a property in an init block of an anonymous object before declaring that property.
Deprecation cycle :
Enforce exhaustiveness for when expressions with non-abstract Java sealed classes Issue : KTLC-366
Component : Core language
Incompatible change type : source
Short summary : Kotlin now checks exhaustiveness more strictly and requires an else branch or a branch that matches the sealed class itself when you use a when expression with a non-abstract Java sealed class. Previously, Kotlin could treat such when expressions as exhaustive even though the Java sealed class itself could be instantiated directly.
Deprecation cycle :
Prohibit operator modifier on getValue() and setValue() functions with too many parameters Issue : KTLC-289
Component : Core language
Incompatible change type : source
Short summary : When you mark the getValue() or setValue() functions with the operator modifier, the compiler now checks that they have the required number of value parameters. The getValue() function must have exactly two value parameters, and the setValue() function must have exactly three. To migrate, remove the operator modifier or change the function signature.
Deprecation cycle :
Prohibit inconsistent type arguments in generic calls Issue : KTLC-373
Component : Core language
Incompatible change type : source
Short summary : When you specify type arguments in a generic call, the compiler now reports an error if one type argument violates an upper-bound constraint that depends on another type argument. If type parameters depend on each other, use type arguments that match those constraints, for example Container<Alpha, AlphaKey>() instead of Container<Alpha, BetaKey>().
Deprecation cycle :
Deprecate references to the javaClass property Issue : KTLC-375
Component : Kotlin/JVM
Incompatible change type : source
Short summary : Kotlin 2.4.0 deprecates property references to the javaClass property to reduce confusion with ::class.java. Use .javaClass to get the runtime Java class of an object, or ::class.java to get a Java class reference.
Deprecation cycle :
Report errors for implicit enum constructor calls that require opt-in Issue : KTLC-359
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an error when an enum entry implicitly calls an enum primary constructor that requires opt-in. To migrate, add @OptIn to the enum class or to each enum entry that calls the constructor.
Deprecation cycle :
Forbid inline modifier on enum entries Issue : KTLC-361
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an error when you use the inline modifier on an enum entry.
Deprecation cycle :
Prohibit array literals outside annotation calls and parameter defaults Issue : KTLC-369
Component : Core language
Incompatible change type : source
Short summary : Using array literals outside annotation calls and default values for annotation parameters now results in an error. To migrate, use arrayOf(...), for example Roles(arrayOf("admin", "user")) instead of Roles(["admin", "user"]).
Deprecation cycle :
Prohibit _root_ide_package_ in CLI compiler mode Issue : KTLC-378
Component : Compiler
Incompatible change type : source
Short summary : Using the IDE-only _root_ide_package_ qualifier in CLI compiler mode now results in an error.
Deprecation cycle :
Correct equality for function references with vararg conversions Issue : KTLC-385
Component : Kotlin/JVM
Incompatible change type : behavioral
Short summary : Kotlin/JVM now treats function references with different conversions as unequal. Previously, Kotlin/JVM ignored vararg conversion in equality checks when the same function reference also used another conversion, so getDefault(::foo) == getDefaultAndVararg(::foo) could return true even though only one side used vararg conversion.
Deprecation cycle :
Enforce opt-in for companion object access Issue : KTLC-386
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an opt-in error when a class name reference resolves to a companion object that requires opt-in. For example, val p = C requires opt-in if C resolves to a companion object marked with an opt-in annotation.
Deprecation cycle :
Report type mismatches from supertypes with nested generic arguments Issue : KTLC-372
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an error when the compiler detects a type mismatch involving a supertype with nested generic arguments. Previously, the compiler could miss this mismatch, which later failed with a ClassCastException. To migrate, use a type argument that matches the receiver's generic type, or remove the explicit type argument so the compiler can infer it.
Deprecation cycle :
Prohibit inferred types with inaccessible declarations Issue : KTLC-363
Component : Core language
Incompatible change type : source
Short summary : Using an inferred type that contains a declaration inaccessible in the current scope now results in an error.
Deprecation cycle :
Standard library Deprecate kotlin.io.readLine() function Issue : KTLC-394
Component : kotlin-stdlib
Incompatible change type : source
Short summary : The kotlin.io.readLine() function is deprecated. Use the readln() function instead of readLine()!!, and the readlnOrNull() function instead of readLine().
Deprecation cycle :
Deprecate AbstractCoroutineContextKey and related APIs Change Random.nextDouble() contract for infinite bounds Issue : KT-84368
Component : kotlin-stdlib
Incompatible change type : behavioral
Short summary : The documented contract for Random.nextDouble(until) now requires the until bound to be finite. Use a finite bound instead.
Deprecation cycle :
Deprecate legacy Kotlin/JS compiler type selection APIs Issue : KT-64275 , KT-84753
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.4.0 removes deprecated Gradle APIs related to selecting the legacy Kotlin/JS compiler type.
Additionally, the KotlinJsCompilerType enum and the KotlinProjectExtension.js() overloads with a compiler type parameter are deprecated. To migrate, remove the compiler type argument from the js() target declaration and use the js {} block instead.
Deprecation cycle :
1.8.0: deprecate legacy Kotlin/JS compiler type constants
2.4.0: remove the deprecated legacy compiler type APIs and report a warning when using KotlinJsCompilerType or KotlinProjectExtension.js() overloads with a compiler type parameter
Deprecate sourceSets in the Kotlin Android extension Issue : KT-74451
Component : Gradle
Incompatible change type : source
Short summary : The sourceSets property in KotlinAndroidProjectExtension is deprecated. To migrate, configure source sets through the Android Gradle plugin's android { sourceSets { ... } } block instead.
Deprecation cycle :
Remove consumable configurations for Kotlin/Native Apple frameworks Issue : KT-74503 , KT-82230
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.4.0 removes generated consumable Gradle configurations that expose Kotlin/Native Apple frameworks as outgoing artifacts.
Deprecation cycle :
Remove deprecated task, compilation, and DSL APIs from the Kotlin Gradle plugin Issue : KT-85509
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.4.0 removes the following deprecated Kotlin Gradle plugin APIs:
Compile task configuration APIs:
KotlinJvmCompile.parentKotlinOptions
KotlinJvmCompile.moduleName
KotlinJvmFactory.createKotlinJvmOptions()
BaseKotlinCompile.moduleName from KotlinCompile and Kotlin2JsCompile tasks
Kotlin Multiplatform hierarchy and target APIs:
DeprecatedKotlinTargetHierarchyDsl
KotlinMultiplatformExtension.targetHierarchy
KotlinTargetComponent.sourcesArtifacts
KotlinTarget.sourceSets
KotlinHierarchyBuilder.withoutCompilations()
KotlinHierarchyBuilder.filterCompilations()
KotlinHierarchyBuilder.withWasm()
KotlinCompilation.defaultSourceSetName
Kotlin compilation task APIs:
Kotlin dependency handler APIs:
KotlinDependencyHandler.enforcedPlatform()
KotlinDependencyHandler.platform() Other deprecated task and extension APIs:
KaptExtension.processors
KotlinTest.excludes
KotlinTest.fileResolver
KotlinTest.execHandleFactory
IncrementalSyncTask.destinationDir
To migrate, remove usages of these APIs and use the replacements suggested by the deprecation diagnostics.
Deprecation cycle :
Deprecate explicit shrunk classpath snapshot configuration Issue : KT-75837
Component : Build tools API
Incompatible change type : source
Short summary : The shrunkClasspathSnapshot configuration parameter in ClasspathSnapshotBasedIncrementalCompilationApproachParameters is deprecated. The shrunk classpath snapshot is an internal incremental compilation cache, so the compiler now creates and manages it automatically under the incremental compiler metadata workingDirectory. To migrate, use the automatically managed snapshot file, instead of passing a value to shrunkClasspathSnapshot.
Deprecation cycle :
Remove redundant ABI validation Gradle DSL elements Issue : KT-80685
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.4.0 simplifies the ABI validation Gradle DSL and removes redundant configuration entries. To migrate, configure report settings directly in abiValidation {} instead of abiValidation { legacyDump { ... } }, remove abiValidation { klib { enabled = ... } }, and use keepLocallyUnsupportedTargets instead of klib.keepUnsupportedTargets.
Deprecation cycle :
Deprecate obsolete Compose compiler Gradle plugin options Issue : KT-85343
Component : Gradle
Incompatible change type : source
Short summary : In Kotlin 2.4.0, the following deprecated Compose compiler Gradle plugin options now report an error when used:
generateFunctionKeyMetaClasses
enableIntrinsicRemember
enableNonSkippingGroupOptimization
enableStrongSkippingMode
stabilityConfigurationFile
ComposeFeatureFlag.StrongSkipping
ComposeFeatureFlag.IntrinsicRemember
Use featureFlags instead of the deprecated feature options, and stabilityConfigurationFiles instead of stabilityConfigurationFile.
Deprecation cycle :
2.0.20: report warnings for enableIntrinsicRemember, enableNonSkippingGroupOptimization, and enableStrongSkippingMode
2.1.0: report a warning for stabilityConfigurationFile
2.4.0: raise the warnings to errors
Report errors for obsolete Kotlin/Native Gradle task APIs Issue : KT-85510
Component : Gradle
Incompatible change type : source
Short summary : The following deprecated Kotlin/Native Gradle task APIs now report an error when used:
AbstractKotlinNativeCompile properties:
KotlinNativeCompile properties:
CInteropProcess properties:
outputFile
konanDataDir
konanHome
defFile
KotlinNativeLink properties:
Additionally, the KotlinNativeLink.compilation property is removed.
Deprecation cycle :
02 June 2026