RenderTwoDimensionalViewport.buildOrObtainChildFor throws assertion failure for a valid vicinity
Steps to reproduce
- Run the example
- Press on FAB
- Press again on FAB
Expected results
You should see the initial widgets on screen since pressing on FAB for second time returns to the initial state.
Actual results
Nothing renders on screen and you'll get an exception log in console due to assertion failure in RenderTwoDimensionalViewport.parentDataOf
Code sample
Code sample
https://dartpad.dev/?id=2c4cc823007d1dc0a9727be611e62f2c
Logs
Logs
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
'package:flutter/src/widgets/two_dimensional_viewport.dart': Failed assertion: line 783 pos 12: '_children.containsValue(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.yml
The relevant error-causing widget was:
TwoDimensionalGridViewport TwoDimensionalGridViewport:file:///main.dart:127:12
When the exception was thrown, this was the stack:
#2 RenderTwoDimensionalViewport.parentDataOf (package:flutter/src/widgets/two_dimensional_viewport.dart:783:12)
#3 RenderTwoDimensionalViewport._moveChild (package:flutter/src/widgets/two_dimensional_viewport.dart:1630:62)
#4 _TwoDimensionalViewportElement.moveRenderObjectChild (package:flutter/src/widgets/two_dimensional_viewport.dart:265:18)
#5 RenderObjectElement.updateSlot (package:flutter/src/widgets/framework.dart:6542:35)
#6 Element.updateSlotForChild.visit (package:flutter/src/widgets/framework.dart:4153:15)
#7 Element.updateSlotForChild.visit (package:flutter/src/widgets/framework.dart:4156:9)
#8 Element.updateSlotForChild.visit (package:flutter/src/widgets/framework.dart:4156:9)
#9 Element.updateSlotForChild.visit (package:flutter/src/widgets/framework.dart:4156:9)
#10 Element.updateSlotForChild (package:flutter/src/widgets/framework.dart:4159:5)
#11 Element.updateChild (package:flutter/src/widgets/framework.dart:3799:11)
#12 _TwoDimensionalViewportElement._buildChild.<anonymous closure> (package:flutter/src/widgets/two_dimensional_viewport.dart:313:33)
#13 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2835:19)
#14 _TwoDimensionalViewportElement._buildChild (package:flutter/src/widgets/two_dimensional_viewport.dart:307:12)
#15 RenderTwoDimensionalViewport.buildOrObtainChildFor.<anonymous closure> (package:flutter/src/widgets/two_dimensional_viewport.dart:1427:23)
#16 RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:2657:59)
#17 PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1071:15)
#18 RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:2657:14)
#19 RenderTwoDimensionalViewport.buildOrObtainChildFor (package:flutter/src/widgets/two_dimensional_viewport.dart:1426:7)
#20 RenderTwoDimensionalGridViewport.layoutChildSequence (package:example/main.dart:227:34)
#21 RenderTwoDimensionalViewport.performLayout (package:flutter/src/widgets/two_dimensional_viewport.dart:1252:5)
#22 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2385:7)
#23 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1025:18)
#24 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1038:15)
#25 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:591:23)
#26 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:986:13)
#27 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#28 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#29 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#30 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
#31 _invoke (dart:ui/hooks.dart:312:13)
#32 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
#33 _drawFrame (dart:ui/hooks.dart:283:31)
(elided 2 frames from class _AssertionError)
The following RenderObject was being processed when the exception was fired: RenderTwoDimensionalGridViewport#9d954 NEEDS-LAYOUT
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
layer: OffsetLayer#dc1bd
engine layer: OffsetEngineLayer#3c122
handles: 2
offset: Offset(0.0, 56.0)
size: Size(984.0, 691.0)
(xIndex: 1, yIndex: 1): RenderRepaintBoundary#71f4f NEEDS-PAINT
needs compositing
parentData: vicinity=(xIndex: 1, yIndex: 1); layoutOffset=Offset(200.0, 200.0); paintOffset=Offset(0.0, 0.0); visible - paintExtent=Size(200.0, 200.0);
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
layer: OffsetLayer#8295b
engine layer: OffsetEngineLayer#415f8
handles: 2
offset: Offset(0.0, 0.0)
size: Size(200.0, 200.0)
metrics: 66.7% useful (1 bad vs 2 good)
diagnosis: insufficient data to draw conclusion (less than five repaints)
child: RenderConstrainedBox#f153a relayoutBoundary=up1 NEEDS-PAINT
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
size: Size(200.0, 200.0)
additionalConstraints: BoxConstraints(w=200.0, h=200.0)
child: _RenderColoredBox#e6003 NEEDS-PAINT
parentData: <none> (can use size)
constraints: BoxConstraints(w=200.0, h=200.0)
size: Size(200.0, 200.0)
behavior: opaque
child: RenderPositionedBox#d4659
parentData: <none> (can use size)
constraints: BoxConstraints(w=200.0, h=200.0)
size: Size(200.0, 200.0)
alignment: Alignment.center
textDirection: ltr
widthFactor: expand
heightFactor: expand
RenderObject: RenderTwoDimensionalGridViewport#9d954 NEEDS-LAYOUT
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
layer: OffsetLayer#dc1bd
engine layer: OffsetEngineLayer#3c122
handles: 2
offset: Offset(0.0, 56.0)
size: Size(984.0, 691.0)
(xIndex: 1, yIndex: 1): RenderRepaintBoundary#71f4f NEEDS-PAINT
needs compositing
parentData: vicinity=(xIndex: 1, yIndex: 1); layoutOffset=Offset(200.0, 200.0); paintOffset=Offset(0.0, 0.0); visible - paintExtent=Size(200.0, 200.0);
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
layer: OffsetLayer#8295b
engine layer: OffsetEngineLayer#415f8
handles: 2
offset: Offset(0.0, 0.0)
size: Size(200.0, 200.0)
metrics: 66.7% useful (1 bad vs 2 good)
diagnosis: insufficient data to draw conclusion (less than five repaints)
child: RenderConstrainedBox#f153a relayoutBoundary=up1 NEEDS-PAINT
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=984.0, 0.0<=h<=691.0)
size: Size(200.0, 200.0)
additionalConstraints: BoxConstraints(w=200.0, h=200.0)
child: _RenderColoredBox#e6003 NEEDS-PAINT
parentData: <none> (can use size)
constraints: BoxConstraints(w=200.0, h=200.0)
size: Size(200.0, 200.0)
behavior: opaque
child: RenderPositionedBox#d4659
parentData: <none> (can use size)
constraints: BoxConstraints(w=200.0, h=200.0)
size: Size(200.0, 200.0)
alignment: Alignment.center
textDirection: ltr
widthFactor: expand
heightFactor: expand
════════════════════════════════════════════════════════════════════════════════
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.16.1, on macOS 14.2.1 23C71 darwin-arm64, locale
en-US)
• Flutter version 3.16.1 on channel stable at /flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7f20e5d18c (6 weeks ago), 2023-11-27 09:47:30 -0800
• Engine revision 22b600f240
• Dart version 3.2.1
• DevTools version 2.28.3
Reproducible using the code sample provided in the dartpad shared above (pasted below for easy access).
code sample
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
scrollBehavior: const MaterialScrollBehavior().copyWith(
// Mouse dragging enabled for this demo
dragDevices: PointerDeviceKind.values.toSet(),
),
debugShowCheckedModeBanner: false,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
final vicinityToKey1 = <ChildVicinity, String>{
const ChildVicinity(xIndex: 1, yIndex: 1): '1',
const ChildVicinity(xIndex: 1, yIndex: 2): '2',
};
final vicinityToKey2 = <ChildVicinity, String>{
const ChildVicinity(xIndex: 0, yIndex: 0): '1',
const ChildVicinity(xIndex: 1, yIndex: 1): '2',
};
class _MyHomePageState extends State<MyHomePage> {
late Map<ChildVicinity, String> vicinityToKey = vicinityToKey1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() {
if (vicinityToKey == vicinityToKey1) {
vicinityToKey = vicinityToKey2;
} else {
vicinityToKey = vicinityToKey1;
}
}),
),
body: TwoDimensionalGridView(
diagonalDragBehavior: DiagonalDragBehavior.free,
delegate: TwoDimensionalChildBuilderDelegate(
maxXIndex: 30,
maxYIndex: 30,
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
builder: (BuildContext context, ChildVicinity vicinity) {
final key = vicinityToKey[vicinity];
if (key != null) {
return AutomaticKeepAlive(
key: ValueKey(key),
child: RepaintBoundary(
child: Container(
color: vicinity.xIndex.isEven && vicinity.yIndex.isEven
? Colors.amber[50]
: (vicinity.xIndex.isOdd && vicinity.yIndex.isOdd
? Colors.purple[50]
: null),
height: 200,
width: 200,
child: Center(child: Text(key)),
),
),
);
}
return null;
}),
),
);
}
}
class TwoDimensionalGridView extends TwoDimensionalScrollView {
const TwoDimensionalGridView({
super.key,
super.primary,
super.mainAxis = Axis.vertical,
super.verticalDetails = const ScrollableDetails.vertical(),
super.horizontalDetails = const ScrollableDetails.horizontal(),
required TwoDimensionalChildBuilderDelegate delegate,
super.cacheExtent,
super.diagonalDragBehavior = DiagonalDragBehavior.none,
super.dragStartBehavior = DragStartBehavior.start,
super.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
super.clipBehavior = Clip.hardEdge,
}) : super(delegate: delegate);
@override
Widget buildViewport(
BuildContext context,
ViewportOffset verticalOffset,
ViewportOffset horizontalOffset,
) {
return TwoDimensionalGridViewport(
horizontalOffset: horizontalOffset,
horizontalAxisDirection: horizontalDetails.direction,
verticalOffset: verticalOffset,
verticalAxisDirection: verticalDetails.direction,
mainAxis: mainAxis,
delegate: delegate as TwoDimensionalChildBuilderDelegate,
cacheExtent: cacheExtent,
clipBehavior: clipBehavior,
);
}
}
class TwoDimensionalGridViewport extends TwoDimensionalViewport {
const TwoDimensionalGridViewport({
super.key,
required super.verticalOffset,
required super.verticalAxisDirection,
required super.horizontalOffset,
required super.horizontalAxisDirection,
required TwoDimensionalChildBuilderDelegate super.delegate,
required super.mainAxis,
super.cacheExtent,
super.clipBehavior = Clip.hardEdge,
});
@override
RenderTwoDimensionalViewport createRenderObject(BuildContext context) {
return RenderTwoDimensionalGridViewport(
horizontalOffset: horizontalOffset,
horizontalAxisDirection: horizontalAxisDirection,
verticalOffset: verticalOffset,
verticalAxisDirection: verticalAxisDirection,
mainAxis: mainAxis,
delegate: delegate as TwoDimensionalChildBuilderDelegate,
childManager: context as TwoDimensionalChildManager,
cacheExtent: cacheExtent,
clipBehavior: clipBehavior,
);
}
@override
void updateRenderObject(
BuildContext context,
RenderTwoDimensionalGridViewport renderObject,
) {
renderObject
..horizontalOffset = horizontalOffset
..horizontalAxisDirection = horizontalAxisDirection
..verticalOffset = verticalOffset
..verticalAxisDirection = verticalAxisDirection
..mainAxis = mainAxis
..delegate = delegate
..cacheExtent = cacheExtent
..clipBehavior = clipBehavior;
}
}
class RenderTwoDimensionalGridViewport extends RenderTwoDimensionalViewport {
RenderTwoDimensionalGridViewport({
required super.horizontalOffset,
required super.horizontalAxisDirection,
required super.verticalOffset,
required super.verticalAxisDirection,
required TwoDimensionalChildBuilderDelegate delegate,
required super.mainAxis,
required super.childManager,
super.cacheExtent = 10,
super.clipBehavior = Clip.hardEdge,
}) : super(delegate: delegate);
@override
void layoutChildSequence() {
final double horizontalPixels = horizontalOffset.pixels;
final double verticalPixels = verticalOffset.pixels;
final double viewportWidth = viewportDimension.width + cacheExtent;
final double viewportHeight = viewportDimension.height + cacheExtent;
final TwoDimensionalChildBuilderDelegate builderDelegate =
delegate as TwoDimensionalChildBuilderDelegate;
final int maxRowIndex = builderDelegate.maxYIndex!;
final int maxColumnIndex = builderDelegate.maxXIndex!;
final int leadingColumn = math.max((horizontalPixels / 200).floor(), 0);
final int leadingRow = math.max((verticalPixels / 200).floor(), 0);
final int trailingColumn = math.min(
((horizontalPixels + viewportWidth) / 200).ceil(),
maxColumnIndex,
);
final int trailingRow = math.min(
((verticalPixels + viewportHeight) / 200).ceil(),
maxRowIndex,
);
double xLayoutOffset = (leadingColumn * 200) - horizontalOffset.pixels;
for (int column = leadingColumn; column <= trailingColumn; column++) {
double yLayoutOffset = (leadingRow * 200) - verticalOffset.pixels;
for (int row = leadingRow; row <= trailingRow; row++) {
final ChildVicinity vicinity =
ChildVicinity(xIndex: column, yIndex: row);
final RenderBox? child = buildOrObtainChildFor(vicinity);
if (child != null) {
child.layout(constraints.loosen());
// Subclasses only need to set the normalized layout offset. The super
// class adjusts for reversed axes.
parentDataOf(child).layoutOffset =
Offset(xLayoutOffset, yLayoutOffset);
}
yLayoutOffset += 200;
}
xLayoutOffset += 200;
}
// Set the min and max scroll extents for each axis.
final double verticalExtent = 200 * (maxRowIndex + 1);
verticalOffset.applyContentDimensions(
0.0,
clampDouble(
verticalExtent - viewportDimension.height, 0.0, double.infinity),
);
final double horizontalExtent = 200 * (maxColumnIndex + 1);
horizontalOffset.applyContentDimensions(
0.0,
clampDouble(
horizontalExtent - viewportDimension.width, 0.0, double.infinity),
);
// Super class handles garbage collection too!
}
}
flutter doctor -v
[!] Flutter (Channel stable, 3.16.5, on macOS 14.1.2 23B92 darwin-arm64, locale en-GB)
• Flutter version 3.16.5 on channel stable at /Users/nexus/dev/sdks/flutter
! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 78666c8dc5 (3 weeks ago), 2023-12-19 16:14:14 -0800
• Engine revision 3f3e560236
• Dart version 3.2.3
• DevTools version 2.28.4
• 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 34.0.0-rc1)
• Android SDK at /Users/nexus/Library/Android/sdk
• Platform android-34, build-tools 34.0.0-rc1
• Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
• Xcode at /Applications/Xcode-15.0.0-Release.Candidate.app/Contents/Developer
• Build 15A240d
• CocoaPods version 1.14.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.3)
• Android Studio at /Users/nexus/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 17.0.6+0-17.0.6b829.9-10027231)
[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
• IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
• Flutter plugin version 76.3.4
• Dart plugin version 232.10072.19
[✓] VS Code (version 1.85.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.80.0
[✓] Connected device (4 available)
• Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 17.2.1 21C66
• Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios • iOS 17.2 21C62
• macOS (desktop) • macos • darwin-arm64 • macOS 14.1.2 23B92 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 120.0.6099.199
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
[✓] Flutter (Channel master, 3.18.0-19.0.pre.118, on macOS 14.1.2 23B92 darwin-arm64, locale en-GB)
• Flutter version 3.18.0-19.0.pre.118 on channel master at /Users/nexus/dev/sdks/flutters
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 29db9dbd44 (3 hours ago), 2024-01-08 23:24:31 -0500
• Engine revision 820645dbcc
• Dart version 3.4.0 (build 3.4.0-4.0.dev)
• DevTools version 2.31.0
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0-rc1)
• Android SDK at /Users/nexus/Library/Android/sdk
• Platform android-34, build-tools 34.0.0-rc1
• Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
• Xcode at /Applications/Xcode-15.0.0-Release.Candidate.app/Contents/Developer
• Build 15A240d
• CocoaPods version 1.14.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.3)
• Android Studio at /Users/nexus/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 17.0.6+0-17.0.6b829.9-10027231)
[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
• IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
• Flutter plugin version 76.3.4
• Dart plugin version 232.10072.19
[✓] VS Code (version 1.85.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.80.0
[✓] Connected device (4 available)
• Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 17.2.1 21C66
• Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios • iOS 17.2 21C62
• macOS (desktop) • macos • darwin-arm64 • macOS 14.1.2 23B92 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 120.0.6099.199
[✓] Network resources
• All expected network resources are available.
• No issues found!
Doing some investigation, I found that the root of this issue is the way _moveChild implemented. _moveChild assigns the child in _children map from "old key" to "new key" causing the child occupying the "new key" being removed from _children, and therefore future calls to get that forgotten child's parentData will fail due to an assertion in parentDataOf. I think the assertion in parentDataOf is unnecessary and it can be removed. WDYT? @Piinks @danagbemava-nc
https://github.com/flutter/flutter/blob/5f17badf4118b474f0b97ee1afe0773ac92b1e4b/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart#L1629-L1638
https://github.com/flutter/flutter/blob/5f17badf4118b474f0b97ee1afe0773ac92b1e4b/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart#L782-L785
Thanks for looking into this. I think the assertion should stay but also maybe it should include those that are being kept alive, and those that are currently in the orphan list?
I wonder if this is something that would be fixed by https://github.com/flutter/flutter/issues/130754 One dimensional scrolling supports this with the findChildIndexCallback for when children have been reordered.
Thanks for looking into this. I think the assertion should stay but also maybe it should include those that are being kept alive, and those that are currently in the orphan list?
I wonder if this is something that would be fixed by #130754 One dimensional scrolling supports this with the findChildIndexCallback for when children have been reordered.
According to my tests 2D foundation is working fine for reordering and the only problem is with the assertion in parentDataOf which can be fixed by including checks for debug orphans and keepAlive bucket. I will open a PR in a few minutes. @Piinks
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.