[BUG] - TypeError: type 'Null' is not a subtype of type 'DocumentLayout' in type cast
Package Version super_editor, GitHub, stable branch (#d519ae5247f7bcfa1722d75ab3c92fc8804bf1d9)
User Info "individual"
To Reproduce not sure but the SuperReader was placed inside a CustomScrollView and the orientation of the device changed to landscape right before the exception occured. So i suppose it must be something to do with the orientation change.
Minimal Reproduction Code If the bug is reproducible in the Example app, you can delete this section. Otherwise, please provide a minimal, runnable code reproduction.
Actual behavior The following exception occured:
TypeError: type 'Null' is not a subtype of type 'DocumentLayout' in type cast
File "super_reader.dart", line 317, in SuperReaderState._createReaderContext.<fn>
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 6900, in SingleChildRenderObjectElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5780, in StatefulElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5771, in StatefulElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 6900, in SingleChildRenderObjectElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5780, in StatefulElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5771, in StatefulElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3963, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5780, in StatefulElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5599, in ComponentElement._firstBuild
File "framework.dart", line 5771, in StatefulElement._firstBuild
File "framework.dart", line 5593, in ComponentElement.mount
File "framework.dart", line 4468, in Element.inflateWidget
File "framework.dart", line 3957, in Element.updateChild
File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5946, in ProxyElement.update
File "inherited_provider.dart", line 523, in _InheritedProviderScopeElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5693, in StatelessElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5780, in StatefulElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5803, in StatefulElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5780, in StatefulElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5803, in StatefulElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5693, in StatelessElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 4090, in Element.updateChildren
File "framework.dart", line 7060, in MultiChildRenderObjectElement.update
File "framework.dart", line 3941, in Element.updateChild
File "slotted_render_object_widget.dart", line 223, in SlottedRenderObjectElement._updateChild
File "slotted_render_object_widget.dart", line 213, in SlottedRenderObjectElement._updateChildren
File "slotted_render_object_widget.dart", line 192, in SlottedRenderObjectElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5693, in StatelessElement.update
File "framework.dart", line 3941, in Element.updateChild
File "framework.dart", line 5642, in ComponentElement.performRebuild
File "framework.dart", line 5333, in Element.rebuild
File "framework.dart", line 5693, in StatelessElement.update
File "framework.dart", line 3941, in Element.updateChild
File "layout_builder.dart", line 207, in _LayoutBuilderElement._rebuildWithConstraints.updateChildCallback
File "framework.dart", line 3038, in BuildOwner.buildScope
File "layout_builder.dart", line 231, in _LayoutBuilderElement._rebuildWithConstraints
File "object.dart", line 2719, in RenderObject.invokeLayoutCallback.<fn>
File "object.dart", line 1098, in PipelineOwner._enableMutationsToDirtySubtrees
File "object.dart", line 2719, in RenderObject.invokeLayoutCallback
File "layout_builder.dart", line 278, in RenderConstrainedLayoutBuilder.rebuildIfNecessary
File "sliver_layout_builder.dart", line 46, in _RenderSliverLayoutBuilder.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "sliver_padding.dart", line 121, in RenderSliverEdgeInsetsPadding.performLayout
File "sliver_padding.dart", line 327, in RenderSliverPadding.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "viewport.dart", line 601, in RenderViewportBase.layoutChildSequence
File "viewport.dart", line 1516, in RenderViewport._attemptLayout
File "viewport.dart", line 1427, in RenderViewport.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 291, in RenderConstrainedBox.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "custom_layout.dart", line 173, in MultiChildLayoutDelegate.layoutChild
File "scaffold.dart", line 1092, in _ScaffoldLayout.performLayout
File "custom_layout.dart", line 237, in MultiChildLayoutDelegate._callPerformLayout
File "custom_layout.dart", line 404, in RenderCustomMultiChildLayoutBox.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "proxy_box.dart", line 3728, in RenderOffstage.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "overlay.dart", line 1002, in _RenderTheaterMixin.layoutChild
File "overlay.dart", line 1311, in _RenderTheater.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "stack.dart", line 510, in RenderStack.layoutPositionedChild
File "stack.dart", line 635, in RenderStack.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "shifted_box.dart", line 705, in RenderConstrainedOverflowBox.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "stack.dart", line 510, in RenderStack.layoutPositionedChild
File "stack.dart", line 635, in RenderStack.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "custom_layout.dart", line 173, in MultiChildLayoutDelegate.layoutChild
File "scaffold.dart", line 1092, in _ScaffoldLayout.performLayout
File "custom_layout.dart", line 237, in MultiChildLayoutDelegate._callPerformLayout
File "custom_layout.dart", line 404, in RenderCustomMultiChildLayoutBox.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "proxy_box.dart", line 3728, in RenderOffstage.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "overlay.dart", line 1002, in _RenderTheaterMixin.layoutChild
File "overlay.dart", line 1311, in _RenderTheater.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
File "object.dart", line 2608, in RenderObject.layout
File "view.dart", line 281, in RenderView.performLayout
File "object.dart", line 2446, in RenderObject._layoutWithoutResize
File "object.dart", line 1052, in PipelineOwner.flushLayout
File "object.dart", line 1065, in PipelineOwner.flushLayout
File "binding.dart", line 602, in RendererBinding.drawFrame
File "binding.dart", line 1164, in WidgetsBinding.drawFrame
File "binding.dart", line 468, in RendererBinding._handlePersistentFrameCallback
File "binding.dart", line 1397, in SchedulerBinding._invokeFrameCallback
File "binding.dart", line 1318, in SchedulerBinding.handleDrawFrame
File "binding.dart", line 1176, in SchedulerBinding._handleDrawFrame
File "hooks.dart", line 312, in _invoke
File "platform_dispatcher.dart", line 419, in PlatformDispatcher._drawFrame
File "hooks.dart", line 283, in _drawFrame
Expected behavior No exception :)
Platform Android 13, Android 14
Flutter version flutter 3.24.1 (not 100% sure but i believe so, maybe one minor version less) dart 3.5.1 (this must be correct)
Additional context I think it must be something with the orientation change, unfortionally i was not yet able to identify the specific issue myself.
i think the actual line in the stacktrace must be off by 1, it must be this line: https://github.com/superlistapp/super_editor/blob/a213ed30104930b52e3870c0b191d3d98f4ced45/super_editor/lib/src/super_reader/super_reader.dart#L318
I found logs from multiple devices, all looking pretty much the same, always with the orientation change. The SuperReader is placed inside a CustomScrollView but i think it does not pop out of view or get into view by changing the device orientation. I also tried to reproduce this issue myself but was not yet able to do so.
@knopp before I assign this to @angelosilvestre can you let me know if this looks related to slivers at all?
@knopp checking in again
It doesn't seem to be.
@quaaantumdev Could you share some details of your widget tree? Reading your stacktrace I suppose your are using LayoutBuilders, Stacks, Positioneds, etc... Also, do you still see this issue in more recent SuperEditor versions?
@matthew-carroll So far I haven't been able to reproduce this issue. I tried changing the orientation while moving SuperReader out of the viewport, but I couldn't trigger this error. It seems that the document's layout is, somehow, being unmounted. I tried messing with the keys, but this also didn't trigger it. The DocumentLayout's key never changes once the SuperReader is initialized. I see some StatefulElement._firstBuild calls in the stack trace, maybe some ancestor widgets are changing around SuperReader. Do you have any ideas on what else could I look?
I did find another crash when selecting some content and rotating the device:
════════ Exception caught by scheduler library ═════════════════════════════════
The following _TypeError was thrown during a scheduler callback:
type 'RenderSliverToBoxAdapter' is not a subtype of type 'RenderBox' in type cast
When the exception was thrown, this was the stack:
#0 _ReadOnlyAndroidDocumentTouchInteractorState._ensureSelectionExtentIsVisible (package:super_editor/src/super_reader/read_only_document_android_touch_interactor.dart:325:77)
read_only_document_android_touch_interactor.dart:325
#1 _ReadOnlyAndroidDocumentTouchInteractorState.didChangeMetrics.<anonymous closure> (package:super_editor/src/super_reader/read_only_document_android_touch_interactor.dart:292:7)
read_only_document_android_touch_interactor.dart:292
#2 Frames.onNextFrame.<anonymous closure> (package:super_editor/src/infrastructure/flutter/flutter_scheduler.dart:72:11)
flutter_scheduler.dart:72
#3 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1442:15)
binding.dart:1442
#4 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1369:11)
binding.dart:1369
#5 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1208:5)
binding.dart:1208
#6 _invoke (dart:ui/hooks.dart:316:13)
hooks.dart:316
#7 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:428:5)
platform_dispatcher.dart:428
#8 _drawFrame (dart:ui/hooks.dart:288:31)
hooks.dart:288
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════
type 'RenderSliverToBoxAdapter' is not a subtype of type 'RenderBox' in type cast
There is a place _ReadOnlyAndroidDocumentTouchInteractorState._ensureSelectionExtentIsVisible we are assuming the the document's RenderObject is a RenderBox, which is no longer the case:
// Determines the offset of the editor in the viewport coordinate
final editorBox = widget.documentKey.currentContext!.findRenderObject() as RenderBox;
@angelosilvestre if the hypothesis is ancestor widgets then you might try writing a variety of tests that pump and repump with ancestor inherited widgets appearing and disappearing and changing values, etc. Whatever you think might cause the problem. Once we're able to capture something in a test, we can fix it.
Based on some recent experience building a custom element, it's really easy to screw up the necessary implementation that's relevant to ancestor widgets. Especially in cases like ContentLayers where we know we're massively hacking the scoped rebuilds.
I did find another crash when selecting some content and rotating the device
If it's related, let's solve it here. If not, please file a new issue and let's address it there.
@matthew-carroll I filed https://github.com/superlistapp/super_editor/issues/2580 because that bug will be much more straightforward to fix, while this ticket might be tricky to reproduce.