Skip to content

[material_ui] MaterialBanner cannot be dismissed once creation context is deactivated #89705

Closed
flutter/packages
#13267

Description

@jiabin87428

Error Info:

Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

Activity

  1. danagbemava-nc commented on Sep 9, 2021

    @danagbemava-nc
    Member

    Hi @jiabin87428, thanks for filing the issue.

    Can you please provide your flutter doctor -v and flutter run --verbose logs, and a minimal complete reproducible code sample?

    Thank you

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Sep 9, 2021
  3. jiabin87428 commented on Sep 29, 2021

    @jiabin87428
    Author

    Hi @jiabin87428, thanks for filing the issue.

    Can you please provide your flutter doctor -v and flutter run --verbose logs, and a minimal complete reproducible code sample?

    Thank you

    flutter doctor -v
    [✓] Flutter (Channel stable, 2.5.0, on macOS 11.5.2 20G95 darwin-x64, locale
        zh-Hans-CN)
        • Flutter version 2.5.0 at /Users/it/Documents/SDK/Flutter
        • Upstream repository https://gitee.com/mirrors/Flutter.git
        • Framework revision 4cc385b4b8 (3 weeks ago), 2021-09-07 23:01:49 -0700
        • Engine revision f0826da7ef
        • Dart version 2.14.0
        • Pub download mirror https://pub.flutter-io.cn
        • Flutter download mirror https://storage.flutter-io.cn
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at /Users/it/Library/Android/sdk
        • Platform android-30, build-tools 30.0.3
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 13.0, Build version 13A233
        • CocoaPods version 1.10.1
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 4.2)
        • Android Studio at /Applications/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 11.0.8+10-b944.6916264)
    
    [✓] VS Code (version 1.60.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.26.0
  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Sep 29, 2021
  5. jiabin87428 commented on Sep 29, 2021

    @jiabin87428
    Author

    Hi @jiabin87428, thanks for filing the issue.

    Can you please provide your flutter doctor -v and flutter run --verbose logs, and a minimal complete reproducible code sample?

    Thank you

    sample code
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    /// First Page
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  TextButton(
                      onPressed: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => const SecondPage()));
                      },
                      child: const Text('Go to the Second Page'))
                ],
              ),
            ));
      }
    }
    
    /// Second Page
    class SecondPage extends StatelessWidget {
      const SecondPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('SecondPage'),
          ),
          body: Center(
              child: TextButton(
                  onPressed: () {
                    ScaffoldMessenger.of(context).showMaterialBanner(MaterialBanner(
                      content: const Text('Press the Dismiss at the First Page'),
                      leading: const Icon(Icons.info),
                      backgroundColor: Colors.yellow,
                      actions: [
                        TextButton(
                          child: const Text('Dismiss'),
                          onPressed: () => ScaffoldMessenger.of(context)
                              .hideCurrentMaterialBanner(),
                        ),
                      ],
                    ));
                  },
                  child: const Text('Create Material Banner'))),
        );
      }
    }
  6. changed the title [-]When the page returns, showMaterialBanner does not disappear, hideCurrentMaterialBanner reports an error[/-] [+]MaterialBanner cannot be dismissed once creation context is deactivated[/+] on Sep 29, 2021
  7. danagbemava-nc commented on Sep 29, 2021

    @danagbemava-nc
    Member

    Issue is reproducible on master and stable with code sample provided by author.

    If a MaterialBanner is created on PageB and PageB is popped from the stack, we are stuck with a MaterialBanner that cannot be dismissed, because it throws the error in the logs below.

    This error is to be expected because the Scaffold that originally created the MaterialBanner is no longer available, however, that then introduces the problem stated above.

    A possible workaround is to use the scaffoldMessengerKey associated with the MaterialApp to be showing and dismissing the MaterialBanner.

    Due to the nature of the MaterialBanner, I believe it would be best if this feature came out of the box without using the scaffoldMessengerKey.

    Some possible solutions might be:

    1. dismiss the banner if the creation context is closed (but that goes against the nature of the Banner)
    2. Attach it to the root context so that it can be deactivated at any time no matter where it is created, although I'm not certain what side effects this will have, if any. (This solution seems similar to using the scaffoldMessengerKey associated with the MaterialApp).

    I am going to label it so that more insight can be provided.

    @jiabin87428 You can try the sample below in the mean time to see if it suits your needs

    sample with scaffoldMessengerKey
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    final globalScaffoldMessenger = GlobalKey<ScaffoldMessengerState>();
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          scaffoldMessengerKey: globalScaffoldMessenger,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    /// First Page
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextButton(
                  onPressed: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => const SecondPage(),
                      ),
                    );
                  },
                  child: const Text('Go to the Second Page'),
                )
              ],
            ),
          ),
        );
      }
    }
    
    /// Second Page
    class SecondPage extends StatelessWidget {
      const SecondPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('SecondPage'),
          ),
          body: Center(
            child: TextButton(
              onPressed: () {
                globalScaffoldMessenger.currentState?.showMaterialBanner(
                  MaterialBanner(
                    content: const Text('Press the Dismiss at the First Page'),
                    leading: const Icon(Icons.info),
                    backgroundColor: Colors.yellow,
                    actions: [
                      TextButton(
                        child: const Text('Dismiss'),
                        onPressed: () {
                          globalScaffoldMessenger.currentState!
                              .hideCurrentMaterialBanner();
                        },
                      ),
                    ],
                  ),
                );
              },
              child: const Text('Create Material Banner'),
            ),
          ),
        );
      }
    }
    
    
    error logs
    Restarted application in 397ms.
    
    ════════ Exception caught by gesture ═══════════════════════════════════════════
    The following assertion was thrown while handling a gesture:
    Looking up a deactivated widget's ancestor is unsafe.
    
    At this point the state of the widget's element tree is no longer stable.
    
    To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
    
    When the exception was thrown, this was the stack
    #0      Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure>
    #1      Element._debugCheckStateIsActiveForAncestorLookup
    #2      Element.dependOnInheritedWidgetOfExactType
    #3      ScaffoldMessenger.maybeOf
    #4      SecondPage.build.<anonymous closure>.<anonymous closure>
    #5      _InkResponseState._handleTap
    #6      GestureRecognizer.invokeCallback
    #7      TapGestureRecognizer.handleTapUp
    #8      BaseTapGestureRecognizer._checkUp
    #9      BaseTapGestureRecognizer.handlePrimaryPointer
    #10     PrimaryPointerGestureRecognizer.handleEvent
    #11     PointerRouter._dispatch
    #12     PointerRouter._dispatchEventToRoutes.<anonymous closure>
    #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:525:8)
    #14     PointerRouter._dispatchEventToRoutes
    #15     PointerRouter.route
    #16     GestureBinding.handleEvent
    #17     GestureBinding.dispatchEvent
    #18     RendererBinding.dispatchEvent
    #19     GestureBinding._handlePointerEventImmediately
    #20     GestureBinding.handlePointerEvent
    #21     GestureBinding._flushPointerEventQueue
    #22     GestureBinding._handlePointerDataPacket
    #26     _invoke1 (dart:ui/hooks.dart:169:10)
    #27     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:293:7)
    #28     _dispatchPointerDataPacket (dart:ui/hooks.dart:88:31)
    (elided 3 frames from dart:async)
    Handler: "onTap"
    Recognizer: TapGestureRecognizer#50180
        debugOwner: GestureDetector
        state: possible
        won arena
        finalPosition: Offset(328.3, 134.3)
        finalLocalPosition: Offset(15.3, 21.3)
        button: 1
        sent tap down
    ════════════════════════════════════════════════════════════════════════════════
    flutter doctor -v
    [✓] Flutter (Channel stable, 2.5.1, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
        • Flutter version 2.5.1 at /Users/nexus/dev/sdks/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision ffb2ecea52 (12 days ago), 2021-09-17 15:26:33 -0400
        • Engine revision b3af521a05
        • Dart version 2.14.2
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-31, build-tools 31.0.0
        • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 12.5.1, Build version 12E507
        • CocoaPods version 1.11.2
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2020.3)
        • Android Studio at /Applications/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 11.0.10+0-b96-7249189)
    
    [✓] VS Code (version 1.60.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.26.0
    
    [✓] Connected device (3 available)
        • iPhone 12 Pro (mobile) • 3685B616-79C3-49F2-9E32-06E6B9A7C48E • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5
          (simulator)
        • macOS (desktop)        • macos                                • darwin-arm64   • macOS 11.5.1 20G80 darwin-arm
        • Chrome (web)           • chrome                               • web-javascript • Google Chrome 94.0.4606.61
    
    • No issues found!
    [✓] Flutter (Channel master, 2.6.0-12.0.pre.135, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
        • Flutter version 2.6.0-12.0.pre.135 at /Users/nexus/dev/sdks/flutters
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 3074c9e04b (6 hours ago), 2021-09-28 22:08:04 -0700
        • Engine revision bccb3a57eb
        • Dart version 2.15.0 (build 2.15.0-156.0.dev)
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-31, build-tools 31.0.0
        • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 12.5.1)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • CocoaPods version 1.11.2
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2020.3)
        • Android Studio at /Applications/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 11.0.10+0-b96-7249189)
    
    [✓] VS Code (version 1.60.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.26.0
    
    [✓] Connected device (3 available)
        • iPhone 12 Pro (mobile) • 3685B616-79C3-49F2-9E32-06E6B9A7C48E • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5
          (simulator)
        • macOS (desktop)        • macos                                • darwin-arm64   • macOS 11.5.1 20G80 darwin-arm
        • Chrome (web)           • chrome                               • web-javascript • Google Chrome 94.0.4606.61
    
    • No issues found!
  8. added
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Sep 29, 2021
  9. 1 remaining item

  10. Miguel-A-Jara commented on Dec 30, 2023

    @Miguel-A-Jara

    In case someone is looking for a working example. Here's some code you can follow:

    1- Create a global scaffold key that has the MaterialApp's context (Remember, MaterialApp is the first widget in our tree, so it has a global context).

    For that purpose, I've created a class that will manage our global keys and that also has null support.

    import 'package:flutter/material.dart';
    
    class GlobalKeys {
      static final GlobalKey<ScaffoldMessengerState> globalScaffoldKey =
          GlobalKey<ScaffoldMessengerState>();
    
      static ScaffoldMessengerState get globalScaffold {
        final context = globalScaffoldKey.currentState;
        if (context == null) {
          throw Exception(
            'ScaffoldMessengerContext not found. You must initialize it in the MaterialApp widget before using it',
          );
        }
    
        return context;
      }
    }
    

    2- Initialize globalScaffoldKey in main.dart.

    void main() {
      runApp(
        const ProviderScope(child: MainApp()),
      );
    }
    
    class MainApp extends StatelessWidget {
      const MainApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          scaffoldMessengerKey: GlobalKeys.globalScaffoldKey // <--- Initialization,
          ...your other properties
        );
      }
    }
    

    3- Finally, use the global scaffold messenger to handle your materialBanner.

    Note

    This function can be anywhere in your code, the only important thing here is how we use the globalScaffoldMessenger.

    void showMaterialBanner() {
          final globalScaffoldMessanger = GlobalKeys.globalScaffold;
    
          //* How to hide materialBanners.
          globalScaffoldMessanger.hideCurrentMaterialBanner();
    
          //* How to show materialBanners.
          globalScaffoldMessanger.showMaterialBanner(
            MaterialBanner(
              content: Text('Hello World!')
              actions: [
                //* Show a close button that works anywhere in your app, regardless of the current context.
                IconButton.filledTonal(
                  icon: const Icon(Icons.close),
                  onPressed: () =>
                      globalScaffoldMessanger.hideCurrentMaterialBanner(),
                ),
              ],
            ),
          );
        }
    
  11. Aturex1 commented on Mar 7, 2024

    @Aturex1

    Maybe you should check this answer on StackOverflow out.
    Just wrap the MaterialBanner action with a Builder and everything works (at least for me)

  12. added
    packageflutter/packages repository. See also p: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Aug 17, 2026
  13. flutter-triage-bot commented on Sep 23, 2026

    @flutter-triage-bot

    This issue is missing a priority label. Please set a priority label when adding the triaged-design label.

  14. added
    P2Important issues not at the top of the work list
    triaged-designTriaged by Design Languages team
    on Sep 29, 2026
  15. changed the title [-]MaterialBanner cannot be dismissed once creation context is deactivated[/-] [+][material_ui] MaterialBanner cannot be dismissed once creation context is deactivated[/+] on Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P2Important issues not at the top of the work listfound in release: 2.5Found to occur in 2.5found in release: 2.6Found to occur in 2.6has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages teamworkaround availableThere is a workaround available to overcome the issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions