From 2f155061af5f4bfe17359d946c294a9c00cf976a Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Wed, 2 Sep 2026 14:03:18 -0700 Subject: [PATCH 1/2] fix(android): skip explicit Kotlin plugin when AGP provides built-in Kotlin AGP 9 enables built-in Kotlin by default and applies the Kotlin plugin itself. Applying it again fails configuration with "Cannot add extension with name 'kotlin'". Guard the explicit apply so it only runs when AGP is not providing Kotlin: AGP 8 and older, or AGP 9 with android.builtInKotlin=false. AGP 10 removes that opt-out, so built-in Kotlin is always active there and the explicit apply must never run. --- android/build.gradle | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 81ec0d4b..cc903145 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -22,7 +22,27 @@ def isNewArchitectureEnabled() { } apply plugin: "com.android.library" -apply plugin: "kotlin-android" +// Android Gradle Plugin 9 ships built-in Kotlin support and applies the Kotlin +// plugin itself. Applying it a second time fails the configuration phase with +// "Cannot add extension with name 'kotlin'". Apply it only when AGP is not +// providing Kotlin: AGP 8 and older, or AGP 9 with android.builtInKotlin=false. +def shouldApplyKotlinPlugin() { + def agpMajor = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger() + if (agpMajor <= 8) { + return true + } + // AGP 10 removes the opt-out: built-in Kotlin is always active there. + if (agpMajor >= 10) { + return false + } + def propertyVal = providers.gradleProperty("android.builtInKotlin").orNull + def builtInKotlinEnabled = propertyVal != null ? propertyVal.toBoolean() : true + return !builtInKotlinEnabled +} + +if (shouldApplyKotlinPlugin()) { + apply plugin: "kotlin-android" +} if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" From f703aa5c06fc0e53fd27097e17c92e4dca6e2f7b Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Fri, 18 Sep 2026 03:21:41 -0700 Subject: [PATCH 2/2] fix(android): check the kotlin extension instead of the AGP version Replace the AGP version / android.builtInKotlin check with a direct test for the registered kotlin extension. The version check reads com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION, which can resolve to a different classpath entry than the AGP actually in use, and the global android.builtInKotlin property can be overridden per module by the com.android.built-in-kotlin plugin -- so both inputs can disagree with reality. Asking whether the kotlin extension exists tests the condition that actually fails, needs no AGP version table, and covers AGP 10 where the opt-out is removed. --- android/build.gradle | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index cc903145..50e0cf53 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -22,25 +22,13 @@ def isNewArchitectureEnabled() { } apply plugin: "com.android.library" -// Android Gradle Plugin 9 ships built-in Kotlin support and applies the Kotlin -// plugin itself. Applying it a second time fails the configuration phase with -// "Cannot add extension with name 'kotlin'". Apply it only when AGP is not -// providing Kotlin: AGP 8 and older, or AGP 9 with android.builtInKotlin=false. -def shouldApplyKotlinPlugin() { - def agpMajor = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger() - if (agpMajor <= 8) { - return true - } - // AGP 10 removes the opt-out: built-in Kotlin is always active there. - if (agpMajor >= 10) { - return false - } - def propertyVal = providers.gradleProperty("android.builtInKotlin").orNull - def builtInKotlinEnabled = propertyVal != null ? propertyVal.toBoolean() : true - return !builtInKotlinEnabled -} - -if (shouldApplyKotlinPlugin()) { +// AGP 9 ships built-in Kotlin support and registers the `kotlin` extension +// itself. Applying the Kotlin plugin on top of it fails configuration with +// "Cannot add extension with name 'kotlin'". Asking for the extension covers +// every way built-in Kotlin can be turned on -- the global default, the +// android.builtInKotlin property, and the per-module com.android.built-in-kotlin +// plugin -- without reading an AGP version number. +if (project.extensions.findByName('kotlin') == null) { apply plugin: "kotlin-android" }