Skip to content

Icon tree shaking ignores IconData implementation getters #126261

Description

@Albert221
import 'package:flutter/material.dart';

enum MyIcons implements IconData {
  test(58332);

  const MyIcons(this.codePoint);

  @override
  final int codePoint;

  @override
  String get fontFamily => 'MaterialIcons';

  @override
  final String? fontPackage = null;

  @override
  final bool matchTextDirection = false;
}

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: const Icon(MyIcons.test),
        ),
      ),
    ),
  );
}

Given the code above in a fresh flutter create project, run the flutter build apk. You'll see fail:

➜  icon_shaking flutter build apk

💪 Building with sound null safety 💪

Target aot_android_asset_bundle failed: IconTreeShakerException: Invalid ConstFinder result. Expected "fontPackage" to be a String, "fontFamily" to be a String, and "codePoint" to be an int, got: {codePoint: 58332, fontPackage: null, matchTextDirection: false, index: 0, _name: test}.

To disable icon tree shaking, pass --no-tree-shake-icons to the requested flutter build command


FAILURE: Build failed with an exception.

* Where:
Script '/Users/albert/fvm/versions/3.7.12/packages/flutter_tools/gradle/flutter.gradle' line: 1157

* What went wrong:
Execution failed for task ':app:compileFlutterBuildRelease'.
> Process 'command '/Users/albert/fvm/versions/3.7.12/bin/flutter'' finished with non-zero exit value 1

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 12s
Running Gradle task 'assembleRelease'...                           13.1s
Gradle task assembleRelease failed with exit code 1

This is because of the fontFamily getter. If I'd replace the getter with a normal field (final fontFamily = 'MaterialIcons';) then it works correctly.

The same problem happens with codePoint and fontPackage.

Of course, the MaterialIcons font is used here just as an example. In our project we use a custom icon font and provide the IconData with such enum.

Here's the source of the thrown exception:

throw IconTreeShakerException._(
'Invalid ConstFinder result. Expected "fontPackage" to be a String, '
'"fontFamily" to be a String, and "codePoint" to be an int, '
'got: $iconDataMap.');

flutter --version
Flutter 3.7.12 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4d9e56e694 (3 weeks ago) • 2023-04-17 21:47:46 -0400
Engine • revision 1a65d409c7
Tools • Dart 2.19.6 • DevTools 2.20.1

Activity

  1. Albert221 commented on May 8, 2023

    @Albert221
    ContributorAuthor

    I understand that tree shaking can't work (or it's a disproportionate amount of work to make it work) with non-constant values. It would be good to explain this in the error message in such case.

    If the error message change is a viable solution I'd be happy to make a PR

  2. danagbemava-nc commented on May 8, 2023

    @danagbemava-nc
    Member

    Reproducible using the code sample & the steps provided above.

    flutter doctor -v
    [✓] Flutter (Channel stable, 3.7.12, on macOS 13.3.1 22E772610a darwin-arm64, locale en-GB)
        • Flutter version 3.7.12 on channel stable at /Users/nexus/dev/sdks/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 4d9e56e694 (3 weeks ago), 2023-04-17 21:47:46 -0400
        • Engine revision 1a65d409c7
        • Dart version 2.19.6
        • DevTools version 2.20.1
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-33, build-tools 33.0.0
        • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 14.3)
        • Xcode at /Applications/Xcode-14.3.0.app/Contents/Developer
        • Build 14E222b
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.1)
        • IntelliJ at /Users/nexus/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
        • Flutter plugin version 73.0.4
        • Dart plugin version 231.8770.15
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
        • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8109.175/IntelliJ IDEA.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.1)
        • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8770.65/IntelliJ IDEA.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.62.0
    
    [✓] Connected device (2 available)
        • macOS (desktop) • macos  • darwin-arm64   • macOS 13.3.1 22E772610a darwin-arm64
        • Chrome (web)    • chrome • web-javascript • Google Chrome 112.0.5615.137
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    • No issues found!
    
    [!] Flutter (Channel master, 3.11.0-2.0.pre.55, on macOS 13.3.1 22E772610a darwin-arm64, locale en-GB)
        • Flutter version 3.11.0-2.0.pre.55 on channel master at /Users/nexus/dev/sdks/flutters
        ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
        ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 835b892d7f (2 days ago), 2023-05-07 01:30:22 +0530
        • Engine revision 23f730efbf
        • Dart version 3.1.0 (build 3.1.0-83.0.dev)
        • DevTools version 2.23.1
        • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-33, build-tools 33.0.0
        • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 14.3)
        • Xcode at /Applications/Xcode-14.3.0.app/Contents/Developer
        • Build 14E222b
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] Android Studio (version 2022.2)
        • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9862592/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.1)
        • IntelliJ at /Users/nexus/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
        • Flutter plugin version 73.0.4
        • Dart plugin version 231.8770.15
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
        • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8109.175/IntelliJ IDEA.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.1)
        • IntelliJ at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.8770.65/IntelliJ IDEA.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.62.0
    
    [✓] Connected device (3 available)
        • Nexus (mobile)  • 00008020-001875E83A38002E • ios            • iOS 16.4.1 20E252
        • macOS (desktop) • macos                     • darwin-arm64   • macOS 13.3.1 22E772610a darwin-arm64
        • Chrome (web)    • chrome                    • web-javascript • Google Chrome 112.0.5615.137
        ! Error: Nexus is busy: Waiting to connect and unlock the device. Xcode will continue when Nexus is finished. (code -10)
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 1 category.
    
    
  3. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    a: buildBuilding flutter applications with the tool
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    c: crashStack traces logged to the console
    and removed
    in triagePresently being triaged by the triage team
    on May 8, 2023
  4. christopherfujino commented on May 8, 2023

    @christopherfujino
    Contributor

    @Albert221 so the issue is here: https://github.com/flutter/engine/blob/main/tools/const_finder/lib/const_finder.dart#L162

        for (final MapEntry<Reference, Constant> kvp in node.fieldValues.entries) {
          if (kvp.value is! PrimitiveConstant<dynamic>) {
            continue;
          }
          final PrimitiveConstant<dynamic> value = kvp.value as PrimitiveConstant<dynamic>;
          instance[kvp.key.asField.name.text] = value.value;
        }

    I'm honestly not sure if getter methods on an enum value will show up in node.fieldValues, but if it does I'm guessing it's hitting the continue because its value is not a PrimitiveConstant.

    As for a tool PR to update this message, all the tool is seeing is that the output from the const_finder is null for fontFamily, I'm not sure how to determine exactly why from the tool. I'm open to suggestions though :)

  5. christopherfujino commented on May 8, 2023

    @christopherfujino
    Contributor

    Backing up, do you really need to implement this as an enum?

  6. Albert221 commented on May 8, 2023

    @Albert221
    ContributorAuthor

    One of the major if not the biggest value from keeping such values as an enum for me is the values property provided by the language itself. I use values in widgetbook; keeping such list manually is error-prone

  7. Albert221 commented on May 8, 2023

    @Albert221
    ContributorAuthor

    I'm not sure how to determine exactly why from the tool. I'm open to suggestions though :)

    I thought of simply providing another paragraph in the exception that explains this case like:

    If the IconData class was implemented in other class, codePoint, fontFamily and fontPackage must be implemented with fields, not getters for the icon tree shaking to work

  8. christopherfujino commented on May 8, 2023

    @christopherfujino
    Contributor

    One of the major if not the biggest value from keeping such values as an enum for me is the values property provided by the language itself. I use values in widgetbook; keeping such list manually is error-prone

    Ahh I see, are you programmatically rendering all your icons?

  9. added
    P3Issues that are less important to the Flutter project
    on May 9, 2023
  10. Albert221 commented on Nov 3, 2023

    @Albert221
    ContributorAuthor

    @christopherfujino we have a storybook that displays a list of all the available icons coming from such enums, as well as use all available values for storybook customizable parts that accept icon

  11. added
    fyi-toolFor the attention of Flutter Tool team
    and removed
    team-toolOwned by Flutter Tool team
    on Jul 11, 2025
  12. dcharkes commented on Mar 10, 2026

    @dcharkes
    Contributor

    @Albert221 I'm currently working on making the flutter icon tree shaker less brittle, and to make tree-shaking of assets a package capability.

    Once everything is done, what you want to do should be possible. It the second bullet point in #181342 (comment).

    However, in the meantime, we will lock down IconData so that the tree-shaker will work more reliably.

    • IconData will be marked final, so you cannot implement it and overwrite fields with getters. (if you currently extend or implement IconData, please migrate off that. See the issue for a migration strategy.)
    • The params will be marked as @mustBeConst causing a lint violation if you pass a non-const value.

    For more info see:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: buildBuilding flutter applications with the toolfound in release: 3.11Found to occur in 3.11found in release: 3.7Found to occur in 3.7has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-engineOwned by Engine teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions