Skip to content

[AGP 9] Better Error for Add-to-app minCompileSdk - #193886

Open
jesswrd wants to merge 7 commits into
flutter:masterfrom
jesswrd:agp9-add-to-app-min-compile-sdk
Open

jesswrd wants to merge 7 commits into
flutter:masterfrom
jesswrd:agp9-add-to-app-min-compile-sdk

Conversation

@jesswrd

@jesswrd jesswrd commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Android now throws an error when an app's compileSdk is lower than that of any library it consumes. This PR adds a more Flutter specific error message for Flutter Android add-to-app users.

Fixes #193682
Related to #181557

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-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.

Adds a best-effort, text-based helper that reports where an Android
project's compileSdk is declared so error messages can point users at
the exact file and line to edit. It handles literals in Groovy/KTS build
scripts (including compileSdkVersion, compileSdkPreview, and the AGP 9
compileSdk { version = release(N) } block), resolves libs.versions.*
references to the matching [versions] entry in gradle/libs.versions.toml,
and falls back to reporting the unresolved expression otherwise.

This is only used for diagnostics and never affects the build result.

Part of flutter#193585
Starting with AGP 9, an app must use a compileSdk that is the same or
higher than the minCompileSdk recorded in every AAR it consumes, and AGP
fails check<Variant>AarMetadata otherwise. In add-to-app, AGP's message
refers to Gradle project paths only (e.g. ':flutter', ':app'), which
makes it hard to tell which project is the host app and which file to
edit.

This adds a task that compares the native host app's compileSdk against
the minCompileSdk of each Flutter AAR (the Flutter module and Flutter
plugins) and throws a GradleException listing:
  * the host app's Gradle project, directory, compileSdk, and the file
    and line where compileSdk is declared (via CompileSdkLocator),
  * each Flutter AAR that requires a higher compileSdk, with its Gradle
    project, directory, and required compileSdk,
  * a copy-pasteable fix for the build script or version catalog.

The message starts with a stable marker so the flutter tool can avoid
printing a duplicate message. The task is wired up in a follow-up
commit.

Part of flutter#193585
…ta check

Registers validateHostAppCompileSdk on the Flutter module and makes the
host app's preBuild depend on it. The task compares the host app's
compileSdk against the minCompileSdk of the Flutter module AAR and each
Flutter plugin AAR (explicit aarMetadata.minCompileSdk, or compileSdk on
AGP 9+), so add-to-app users get a Flutter-specific error that names the
host project, each Flutter AAR, and the file to edit.

Part of flutter#193585
In add-to-app, AGP 9 compares the host app's compileSdk against every
AAR, not the Flutter module against its plugins. The existing module vs.
plugin checks (ValidateCompileSdkVersionTask and the PluginHandler
warning) warned on builds that succeed, pointed at the regenerated
.android/app/build.gradle, and could contradict validateHostAppCompileSdk.

Skip the compileSdk half of ValidateCompileSdkVersionTask for modules
(the NDK check is unchanged) and only print the PluginHandler warning for
Flutter app projects.

Part of flutter#193585
…p message

AGP 9 reworded the AAR metadata minCompileSdk failure, so
minCompileSdkVersionHandler no longer matched it. Match the new
"Dependency '...' requires libraries and applications that" line and
name the dependency in the Flutter Fix box.

Add flutterHostAppCompileSdkHandler ahead of it: when the Flutter Gradle
plugin's validateHostAppCompileSdk message is present, it already names
the host app, Flutter AARs, and file to edit, so the tool doesn't print a
second fix.

Part of flutter#193585
…eeds

After flutter build aar, read minCompileSdk from each built AAR's
META-INF/com/android/build/gradle/aar-metadata.properties and add a
"Consuming the Module" step listing each AAR, its path, and the
compileSdk the host app must use under AGP 9. Also say
build.gradle(.kts) instead of build.gradle.

Part of flutter#193585
@jesswrd
jesswrd requested a review from a team as a code owner October 6, 2026 05:20
@jesswrd
jesswrd requested review from gmackall and removed request for a team October 6, 2026 05:20
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Oct 6, 2026
@jesswrd
jesswrd removed the request for review from gmackall October 6, 2026 05:20
@github-actions github-actions Bot added platform-android Android applications specifically tool Affects the "flutter" command-line tool. See also t: labels. team-android Owned by Android platform team labels Oct 6, 2026
@jesswrd jesswrd mentioned this pull request Oct 6, 2026
17 of 27 tasks

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a validation mechanism for add-to-app Flutter modules to ensure that the native Android host app compiles against an Android SDK version that is equal to or higher than the minimum required by any consumed Flutter AARs. It adds CompileSdkLocator to locate compileSdk declarations, registers ValidateHostAppCompileSdkTask to perform the validation before AGP checks, and updates error handling and instructions for consuming AARs. Feedback suggests improving the robustness of findAarMinCompileSdks in gradle.dart by safely checking the type of metadata.content and catching all exceptions during AAR processing to prevent potential crashes from malformed or corrupted files.

Comment on lines +1216 to +1231
try {
final Archive archive = ZipDecoder().decodeBytes(entity.readAsBytesSync());
final ArchiveFile? metadata = archive.findFile(_kAarMetadataPath);
if (metadata == null) {
continue;
}
final String contents = utf8.decode(metadata.content as List<int>);
final Match? match = _aarMinCompileSdkPattern.firstMatch(contents);
if (match != null) {
aarMinCompileSdks[entity] = int.parse(match.group(1)!);
}
} on ArchiveException {
continue;
} on FileSystemException {
continue;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of findAarMinCompileSdks casts metadata.content directly to List<int> and only catches ArchiveException and FileSystemException. If metadata.content is null or not a List<int>, a TypeError will be thrown. Additionally, if utf8.decode fails on corrupted data, a FormatException will be thrown. Since these are not caught, they will crash the flutter tool.\n\nWe should safely check the type of metadata.content and catch all exceptions during the AAR processing to ensure the tool is robust against corrupted or malformed AAR files.

    try {\n      final Archive archive = ZipDecoder().decodeBytes(entity.readAsBytesSync());\n      final ArchiveFile? metadata = archive.findFile(_kAarMetadataPath);\n      if (metadata == null) {\n        continue;\n      }\n      final Object? content = metadata.content;\n      if (content is! List<int>) {\n        continue;\n      }\n      final String contents = utf8.decode(content);\n      final Match? match = _aarMinCompileSdkPattern.firstMatch(contents);\n      if (match != null) {\n        aarMinCompileSdks[entity] = int.parse(match.group(1)!);\n      }\n    } catch (e) {\n      continue;\n    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD platform-android Android applications specifically team-android Owned by Android platform team tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[AGP 9] Add Helpful Error Message For Add-to-app

1 participant