Skip to content

Scaffold.bottomSheet throws a duplicate GlobalKey when being quickly removed/added to the Scaffold #83668

@matuella

Description

@matuella

Internal: b/237046314

Internal: b/237030160

Just like the title says, when quickly removing/adding Scaffold.bottomSheet property (setting to null), it throws a duplicate GlobalKey error.

Steps to Reproduce

1a. Run the code below in any mobile simulator/emulator;

Reproducible Error
import 'package:flutter/material.dart';

void main() => runApp(BottomSheetApp());

class BottomSheetApp extends StatefulWidget {
  @override
  _BottomSheetAppState createState() => _BottomSheetAppState();
}

class _BottomSheetAppState extends State<BottomSheetApp> {
  bool showsSheet = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            child: Text('Toggle sheet'),
            onPressed: () => setState(() => showsSheet = !showsSheet),
          ),
        ),
        bottomSheet: showsSheet ? Container(color: Colors.blue) : null,
      ),
    );
  }
}

1b. Emulate the same scenario using this dartpad that I've created with the code above
2. Press the Toggle Sheet button twice (or as many times as you want) really fast (I think < ~200ms is enough).

flutter doctor -v
[✓] Flutter (Channel stable, 2.2.0, on macOS 11.2.1 20D74 darwin-x64, locale en-BR)
    • Flutter version 2.2.0 at /Users/guilhermematuella/flutter
    • Framework revision b22742018b (2 weeks ago), 2021-05-14 19:12:57 -0700
    • Engine revision a9d88a4d18
    • Dart version 2.13.0

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/guilhermematuella/Library/Android/sdk
    • Platform android-30, build-tools 30.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.2, Build version 12B45b
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.56.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.22.0

[✓] Connected device (3 available)
    • iPhone SE (2nd generation) (mobile) • 14A9935F-51BF-41D7-AE3B-94B23FBDDCD7 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-2 (simulator)
    • macOS (desktop)                     • macos                                • darwin-x64     • macOS 11.2.1 20D74 darwin-x64
    • Chrome (web)                        • chrome                               • web-javascript • Google Chrome 90.0.4430.212

• No issues found!
Error

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown while finalizing the widget tree:
Duplicate GlobalKey detected in widget tree.

The following GlobalKey was specified multiple times in the widget tree. This will lead to parts of the widget tree being truncated unexpectedly, because the second time a key is seen, the previous instance is moved to the new location. The key was:
- [GlobalKey#ee989]
This was determined by noticing that after the widget with the above global key was moved out of its previous parent, that previous parent never updated during this frame, meaning that it either did not update at all or updated before the widget was moved, in either case implying that it still thinks that it should have a child with that global key.
The specific parent that did not update after having one or more children forcibly removed due to GlobalKey reparenting is:
- _InheritedResetNotifier
A GlobalKey can only be specified on one widget at a time in the widget tree.
When the exception was thrown, this was the stack
#0      BuildOwner.finalizeTree.<anonymous closure>
package:flutter/…/widgets/framework.dart:2900
#1      BuildOwner.finalizeTree
package:flutter/…/widgets/framework.dart:2925

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work listc: regressionIt was better in the past than it is nowcustomer: money (g3)f: material designflutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions