Repository navigation
[FGP] Report the real error when applying kotlin-android fails - #195080
Conversation
detectApplyingKotlinGradlePlugin caught every exception from
pluginManager.apply("kotlin-android") and logged that KGP was not on the
classpath. With android.builtInKotlin=false and android.newDsl=true, KGP
throws an incompatibility error that this hid. Catch only
UnknownPluginException so other failures reach the user.
| if (!pluginState.hasAppPlugin && !pluginState.hasLibPlugin) return@subprojects | ||
|
|
||
| if (!isBuiltInKotlinEnabled(project, agpVersion) && !pluginState.hasKgpPlugin) { | ||
| // Only a missing plugin is handled here. Any other failure, such as the |
There was a problem hiding this comment.
This comment feels super specific but I think that is ok. Other reviewers chime in.
There was a problem hiding this comment.
Code Review
This pull request refactors the Kotlin Gradle Plugin (KGP) application logic in FlutterPluginUtils.kt to catch UnknownPluginException instead of a generic Exception when applying kotlin-android. This allows other build failures, such as KGP rejecting specific DSL configurations, to propagate correctly. Corresponding unit tests in FlutterPluginUtilsTest.kt have been updated, and a new test has been added to verify this propagation behavior. There are no review comments, and I have no feedback to provide.
|
@jesswrd I want your opinion on if this should be cherry picked. |
|
@reidbaker-agent can you add a comment with the before and after of the log message that users would get? |
|
Here is the exact build output before and after this change for a template Flutter app ( Before this PR
After this PRThe non- (When KGP is genuinely absent from the classpath, |
|
autosubmit label was removed for flutter/flutter/195080, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR. |
flutter/flutter@c091098...5e805bf 2026-10-30 [email protected] Fix/shared thread merger expired lease (flutter/flutter#194200) 2026-10-30 [email protected] [FGP] Report the real error when applying kotlin-android fails (flutter/flutter#195080) 2026-10-30 [email protected] [Impeller] Minify GLSL shaders (flutter/flutter#195240) 2026-10-30 [email protected] Roll Packages from 0b72e92 to 3742a4e (12 revisions) (flutter/flutter#195686) 2026-10-30 [email protected] Roll Dart SDK from 52c908c00267 to fe609902984b (2 revisions) (flutter/flutter#195679) 2026-10-30 [email protected] Roll Skia from 0789f2ab93b8 to c0c46ee9f938 (1 revision) (flutter/flutter#195671) 2026-10-30 [email protected] Roll Fuchsia Linux SDK from SORPfa9tgFn83M1CR... to x2SqGbVUkOm4d6vk_... (flutter/flutter#195670) 2026-10-30 [email protected] Roll Skia from 4470b8abaad6 to 0789f2ab93b8 (2 revisions) (flutter/flutter#195665) 2026-10-30 [email protected] Roll Dart SDK from 89f7a35480d6 to 52c908c00267 (1 revision) (flutter/flutter#195659) 2026-10-30 [email protected] Roll Skia from 9f4e3117465e to 4470b8abaad6 (4 revisions) (flutter/flutter#195658) 2026-10-30 [email protected] Roll Skia from ec13cd547e98 to 9f4e3117465e (1 revision) (flutter/flutter#195650) 2026-10-30 [email protected] [web] Keep semantics editing state while the text input connection is open (flutter/flutter#195141) 2026-10-30 [email protected] [web_paragraph] Fix multi-span BiDi span order and region direction (flutter/flutter#194980) 2026-10-30 [email protected] [web] Unskip web tests that pass on CanvasKit and Skwasm: accessibility_inspector_test, color_filter_test (flutter/flutter#195541) 2026-10-30 [email protected] Roll Skia from 4ecd22a4a1d0 to ec13cd547e98 (10 revisions) (flutter/flutter#195647) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…ls (#195691) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: #181557 ### Impact Description: Cherry-pick of #195080 (also tracks #189236 and #180137). On Flutter 3.50 beta (`flutter-3.50-candidate.0`), when an Android project sets `android.newDsl=true` while `android.builtInKotlin=false`, `FlutterPluginUtils.detectApplyingKotlinGradlePlugin` catches all exceptions from `pluginManager.apply("kotlin-android")`. Instead of surfacing the Kotlin Gradle Plugin's actual incompatibility message (`The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSL` along with instructions to set `android.builtInKotlin=true` or `android.newDsl=false`), Flutter Gradle Plugin prints `"Applying the Kotlin Android Plugin (KGP) was unsuccessful. KGP was not found on the classpath."` and the build fails later with an unrelated script compilation error (`Unresolved reference: kotlin` / `compilerOptions`). Narrowing the catch to `UnknownPluginException` surfaces KGP's real error and remediation guidance to developers adopting AGP 9's new DSL in 3.50. ### Changelog Description: [flutter/181557](#181557): Android builds with `android.newDsl=true` and `android.builtInKotlin=false` misreport a missing Kotlin Gradle Plugin instead of the actual incompatibility error. ### Workaround: Set `android.builtInKotlin=true` (after migrating off `org.jetbrains.kotlin.android`) or `android.newDsl=false` in `android/gradle.properties`; however, without this fix the build output misleads developers into debugging a missing KGP classpath dependency instead of the `builtInKotlin`/`newDsl` mismatch. ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: 1. Create a new Flutter Android app (`flutter create my_app`) using AGP 9.x. 2. Set `android.builtInKotlin=false` and `android.newDsl=true` in `android/gradle.properties`. 3. Run `flutter build apk` and verify that Gradle reports KGP's real error (`The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSL` with remediation steps) instead of `"KGP was not found on the classpath."` (also covered by unit tests in `FlutterPluginUtilsTest.kt`).
…er#195080) When `android.builtInKotlin=false` and `android.newDsl=true`, the Flutter Gradle Plugin said "KGP was not found on the classpath". The real error from the Kotlin Gradle Plugin was hidden. The build then failed with an unrelated script compilation error. This change catches only the missing-plugin case, so other failures show the Kotlin Gradle Plugin's own message. Related to flutter#181557 and flutter#189236. <details><summary>Agent authored details</summary> `FlutterPluginUtils.detectApplyingKotlinGradlePlugin` wrapped `pluginManager.apply("kotlin-android")` in `catch (_: Exception)`. It now catches `org.gradle.api.plugins.UnknownPluginException`, which Gradle's `DefaultPluginManager.apply(String)` throws for an unknown plugin id. Failures inside the plugin's own `apply` are wrapped differently and now propagate. Before (AGP 9.3.1, KGP 2.4.20, template app, `builtInKotlin=false`, `newDsl=true`): ``` Applying the Kotlin Android Plugin (KGP) was unsuccessful. KGP was not found on the classpath. ... * What went wrong: Script compilation errors: Line 41: kotlin { ``` After: ``` > Failed to apply plugin 'kotlin-android'. > ⛔ Failed to apply plugin 'org.jetbrains.kotlin.android' The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSL (`android.newDsl=true` is enabled by default). Solution: Set `android.builtInKotlin=true` in `gradle.properties` and migrate to built-in Kotlin (see https://kotl.in/gradle/agp-built-in-kotlin for guidance), or set `android.newDsl=false` in `gradle.properties` to temporarily bypass this issue. ``` Tests: the two existing "KGP fails to apply" tests now throw `UnknownPluginException`. Added `propagates a KGP failure that is not a missing plugin`. No comments, docs or tests removed. Verification: `./gradlew test` (JDK 17) passed. ktlint 1.5.0 with the CI flags passed. A manual build of the template app was run before and after. Note: with AGP 9, KGP resolves through AGP even when `settings.gradle.kts` does not declare it, so the missing-plugin branch is hard to reach in practice. This applies cleanly to `flutter-3.50-candidate.0`; `FlutterPluginUtils.kt` is identical there. </details> ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant in-code documentation (doc comments with `///`). - [ ] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
When
android.builtInKotlin=falseandandroid.newDsl=true, the Flutter Gradle Plugin said "KGP was not found on the classpath". The real error from the Kotlin Gradle Plugin was hidden. The build then failed with an unrelated script compilation error.This change catches only the missing-plugin case, so other failures show the Kotlin Gradle Plugin's own message.
Related to #181557 and #189236.
Agent authored details
FlutterPluginUtils.detectApplyingKotlinGradlePluginwrappedpluginManager.apply("kotlin-android")incatch (_: Exception). It now catchesorg.gradle.api.plugins.UnknownPluginException, which Gradle'sDefaultPluginManager.apply(String)throws for an unknown plugin id. Failures inside the plugin's ownapplyare wrapped differently and now propagate.Before (AGP 9.3.1, KGP 2.4.20, template app,
builtInKotlin=false,newDsl=true):After:
Tests: the two existing "KGP fails to apply" tests now throw
UnknownPluginException. Addedpropagates a KGP failure that is not a missing plugin.No comments, docs or tests removed.
Verification:
./gradlew test(JDK 17) passed. ktlint 1.5.0 with the CI flags passed. A manual build of the template app was run before and after.Note: with AGP 9, KGP resolves through AGP even when
settings.gradle.ktsdoes not declare it, so the missing-plugin branch is hard to reach in practice.This applies cleanly to
flutter-3.50-candidate.0;FlutterPluginUtils.ktis identical there.Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.