Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when modifying GlobalKey Widget index and parent in Column's Children #120762

Closed
yiiim opened this issue Feb 15, 2023 · 2 comments · Fixed by #120773
Closed

Crash when modifying GlobalKey Widget index and parent in Column's Children #120762

yiiim opened this issue Feb 15, 2023 · 2 comments · Fixed by #120773
Labels
c: crash Stack traces logged to the console found in release: 3.7 Found to occur in 3.7 found in release: 3.8 Found to occur in 3.8 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on r: fixed Issue is closed as already fixed in a newer version

Comments

@yiiim
Copy link
Member

yiiim commented Feb 15, 2023

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Click FloatingActionButton
Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey _globalKey = GlobalKey();
  bool _updated = false;

  @override
  Widget build(BuildContext context) {
    late List<Widget> widgets;
    if (_updated) {
      widgets = [
        const Text("1"),
        const Text("3"),
        SizedBox(child: Text("2", key: _globalKey)),
      ];
    } else {
      widgets = [
        const Text("1"),
        Text("2", key: _globalKey),
        const Text("3"),
      ];
    }
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: widgets,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() => _updated = true);
          },
          tooltip: 'Run',
          child: const Icon(Icons.play_arrow),
        ),
      ),
    );
  }
}

Logs
Restarted application in 275ms.

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building _BodyBuilder:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 6320 pos 12: '_children.contains(child)': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was
Scaffold
When the exception was thrown, this was the stack
#2      MultiChildRenderObjectElement.forgetChild
#3      Element._retakeInactiveElement
...     Normal element mounting (4 frames)
#7      Element.inflateWidget
#8      MultiChildRenderObjectElement.inflateWidget
#9      Element.updateChild
#10     RenderObjectElement.updateChildren
#11     MultiChildRenderObjectElement.update
#12     Element.updateChild
#13     SingleChildRenderObjectElement.update
#14     Element.updateChild
#15     ComponentElement.performRebuild
#16     Element.rebuild
#17     StatelessElement.update
#18     Element.updateChild
#19     ComponentElement.performRebuild
#20     Element.rebuild
#21     ProxyElement.update
#22     Element.updateChild
#23     ComponentElement.performRebuild
#24     Element.rebuild
#25     ProxyElement.update
#26     Element.updateChild
#27     RenderObjectElement.updateChildren
#28     MultiChildRenderObjectElement.update
#29     Element.updateChild
#30     ComponentElement.performRebuild
#31     StatefulElement.performRebuild
#32     Element.rebuild
#33     StatefulElement.update
#34     Element.updateChild
#35     ComponentElement.performRebuild
#36     Element.rebuild
#37     ProxyElement.update
#38     Element.updateChild
#39     ComponentElement.performRebuild
#40     StatefulElement.performRebuild
#41     Element.rebuild
#42     StatefulElement.update
#43     Element.updateChild
#44     SingleChildRenderObjectElement.update
#45     Element.updateChild
#46     ComponentElement.performRebuild
#47     Element.rebuild
#48     ProxyElement.update
#49     Element.updateChild
#50     SingleChildRenderObjectElement.update
#51     Element.updateChild
#52     ComponentElement.performRebuild
#53     StatefulElement.performRebuild
#54     Element.rebuild
#55     StatefulElement.update
#56     Element.updateChild
#57     ComponentElement.performRebuild
#58     StatefulElement.performRebuild
#59     Element.rebuild
#60     StatefulElement.update
#61     Element.updateChild
#62     ComponentElement.performRebuild
#63     Element.rebuild
#64     ProxyElement.update
#65     Element.updateChild
#66     ComponentElement.performRebuild
#67     Element.rebuild
#68     ProxyElement.update
#69     Element.updateChild
#70     ComponentElement.performRebuild
#71     StatefulElement.performRebuild
#72     Element.rebuild
#73     StatefulElement.update
#74     Element.updateChild
#75     ComponentElement.performRebuild
#76     Element.rebuild
#77     ProxyElement.update
#78     Element.updateChild
#79     ComponentElement.performRebuild
#80     StatefulElement.performRebuild
#81     Element.rebuild
#82     StatefulElement.update
#83     Element.updateChild
#84     SingleChildRenderObjectElement.update
#85     Element.updateChild
#86     ComponentElement.performRebuild
#87     Element.rebuild
#88     StatelessElement.update
#89     Element.updateChild
#90     SingleChildRenderObjectElement.update
#91     Element.updateChild
#92     SingleChildRenderObjectElement.update
#93     Element.updateChild
#94     ComponentElement.performRebuild
#95     StatefulElement.performRebuild
#96     Element.rebuild
#97     StatefulElement.update
#98     Element.updateChild
#99     RenderObjectElement.updateChildren
#100    MultiChildRenderObjectElement.update
#101    Element.updateChild
#102    ComponentElement.performRebuild
#103    StatefulElement.performRebuild
#104    Element.rebuild
#105    StatefulElement.update
#106    Element.updateChild
#107    SingleChildRenderObjectElement.update
#108    Element.updateChild
#109    ComponentElement.performRebuild
#110    StatefulElement.performRebuild
#111    Element.rebuild
#112    StatefulElement.update
#113    Element.updateChild
#114    SingleChildRenderObjectElement.update
#115    Element.updateChild
#116    ComponentElement.performRebuild
#117    StatefulElement.performRebuild
#118    Element.rebuild
#119    StatefulElement.update
#120    Element.updateChild
#121    SingleChildRenderObjectElement.update
#122    Element.updateChild
#123    ComponentElement.performRebuild
#124    StatefulElement.performRebuild
#125    Element.rebuild
#126    StatefulElement.update
#127    Element.updateChild
#128    ComponentElement.performRebuild
#129    Element.rebuild
#130    StatelessElement.update
#131    Element.updateChild
#132    ComponentElement.performRebuild
#133    StatefulElement.performRebuild
#134    Element.rebuild
#135    StatefulElement.update
#136    Element.updateChild
#137    SingleChildRenderObjectElement.update
#138    Element.updateChild
#139    SingleChildRenderObjectElement.update
#140    Element.updateChild
#141    ComponentElement.performRebuild
#142    Element.rebuild
#143    ProxyElement.update
#144    _InheritedNotifierElement.update
#145    Element.updateChild
#146    SingleChildRenderObjectElement.update
#147    Element.updateChild
#148    ComponentElement.performRebuild
#149    StatefulElement.performRebuild
#150    Element.rebuild
#151    StatefulElement.update
#152    Element.updateChild
#153    ComponentElement.performRebuild
#154    Element.rebuild
#155    ProxyElement.update
#156    Element.updateChild
#157    ComponentElement.performRebuild
#158    Element.rebuild
#159    ProxyElement.update
#160    Element.updateChild
#161    ComponentElement.performRebuild
#162    StatefulElement.performRebuild
#163    Element.rebuild
#164    StatefulElement.update
#165    Element.updateChild
#166    ComponentElement.performRebuild
#167    Element.rebuild
#168    StatelessElement.update
#169    Element.updateChild
#170    ComponentElement.performRebuild
#171    Element.rebuild
#172    StatelessElement.update
#173    Element.updateChild
#174    SingleChildRenderObjectElement.update
#175    Element.updateChild
#176    ComponentElement.performRebuild
#177    Element.rebuild
#178    ProxyElement.update
#179    Element.updateChild
#180    ComponentElement.performRebuild
#181    Element.rebuild
#182    ProxyElement.update
#183    Element.updateChild
#184    ComponentElement.performRebuild
#185    StatefulElement.performRebuild
#186    Element.rebuild
#187    StatefulElement.update
#188    Element.updateChild
#189    ComponentElement.performRebuild
#190    StatefulElement.performRebuild
#191    Element.rebuild
#192    StatefulElement.update
#193    Element.updateChild
#194    ComponentElement.performRebuild
#195    StatefulElement.performRebuild
#196    Element.rebuild
#197    BuildOwner.buildScope
#198    WidgetsBinding.drawFrame
#199    RendererBinding._handlePersistentFrameCallback
#200    SchedulerBinding._invokeFrameCallback
#201    SchedulerBinding.handleDrawFrame
#202    SchedulerBinding._handleDrawFrame
#206    _invoke (dart:ui/hooks.dart:151:10)
#207    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#208    _drawFrame (dart:ui/hooks.dart:115:31)
(elided 5 frames from class _AssertionError and dart:async)
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
Each child must be laid out exactly once.
The relevant error-causing widget was
Scaffold
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
Updated layout information required for RenderErrorBox#1c7ba NEEDS-LAYOUT NEEDS-PAINT to calculate semantics.
'package:flutter/src/rendering/object.dart':
Failed assertion: line 2817 pos 12: '!_needsLayout'

════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
Duplicate GlobalKey detected in widget tree.
════════════════════════════════════════════════════════════════════════════════

@exaby73 exaby73 added the in triage Presently being triaged by the triage team label Feb 15, 2023
@exaby73
Copy link
Member

exaby73 commented Feb 15, 2023

Triage report

I can reproduce this issue on Master (3.8.0-12.0.pre.68).

Code Sample (Same as OP)
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey _globalKey = GlobalKey();
  bool _updated = false;

  @override
  Widget build(BuildContext context) {
    late List<Widget> widgets;
    if (_updated) {
      widgets = [
        const Text("1"),
        const Text("3"),
        SizedBox(child: Text("2", key: _globalKey)),
      ];
    } else {
      widgets = [
        const Text("1"),
        Text("2", key: _globalKey),
        const Text("3"),
      ];
    }
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: widgets,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() => _updated = true);
          },
          tooltip: 'Run',
          child: const Icon(Icons.play_arrow),
        ),
      ),
    );
  }
}
Logs
#201    Element.rebuild
framework.dart:4672
#202    StatefulElement.update
framework.dart:5140
#203    Element.updateChild
framework.dart:3655
#204    ComponentElement.performRebuild
framework.dart:4977
#205    StatefulElement.performRebuild
framework.dart:5117
#206    Element.rebuild
framework.dart:4672
#207    StatefulElement.update
framework.dart:5140
#208    Element.updateChild
framework.dart:3655
#209    ComponentElement.performRebuild
framework.dart:4977
#210    StatefulElement.performRebuild
framework.dart:5117
#211    Element.rebuild
framework.dart:4672
#212    BuildOwner.buildScope
framework.dart:2749
#213    WidgetsBinding.drawFrame
binding.dart:866
#214    RendererBinding._handlePersistentFrameCallback
binding.dart:378
#215    SchedulerBinding._invokeFrameCallback
binding.dart:1286
#216    SchedulerBinding.handleDrawFrame
binding.dart:1216
#217    SchedulerBinding._handleDrawFrame
binding.dart:1074
#218    _invoke (dart:ui/hooks.dart:142:13)
#219    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:338:5)
#220    _drawFrame (dart:ui/hooks.dart:112:31)
(elided 2 frames from class _AssertionError)
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
Each child must be laid out exactly once.
The relevant error-causing widget was
Scaffold
main.dart:35
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
Updated layout information required for RenderErrorBox#a9242 NEEDS-LAYOUT NEEDS-PAINT to calculate semantics.
'package:flutter/src/rendering/object.dart':
object.dart:1
Failed assertion: line 3242 pos 12: '!_needsLayout'

════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
Duplicate GlobalKey detected in widget tree.
════════════════════════════════════════════════════════════════════════════════

@exaby73 exaby73 added c: crash Stack traces logged to the console framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.7 Found to occur in 3.7 found in release: 3.8 Found to occur in 3.8 and removed in triage Presently being triaged by the triage team labels Feb 15, 2023
@exaby73 exaby73 added the r: fixed Issue is closed as already fixed in a newer version label Feb 20, 2023
@github-actions
Copy link

github-actions bot commented Mar 6, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: crash Stack traces logged to the console found in release: 3.7 Found to occur in 3.7 found in release: 3.8 Found to occur in 3.8 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on r: fixed Issue is closed as already fixed in a newer version
Projects
None yet
2 participants