Understanding Flutter Rendering Errors

 ・ 9 min

photo by Karsten Winegeart on Unsplash

When working with Flutter, UI-related errors are probably the ones you'll encounter most often. Every time they happen, the error output in the console is so long and complex that I often had no idea how to solve them. So this time, I'm going to go through the output messages one by one and organize how to approach them!

Error Message#

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.
Viewports expand in the scrolling direction to fill their container. In this case, a vertical viewport was given an unlimited amount of vertical space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget.
If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column or Wrap instead. Otherwise, consider using a CustomScrollView to concatenate arbitrary slivers into a single scrollable.
 
The relevant error-causing widget was:
    ListView ListView:file:///Users/ittae/development/ittae/lib/src/features/calendar/presentation/attendance_pages/widgets/attendance_result.dart:21:21
 
When the exception was thrown, this was the stack:
#0      debugCheckHasBoundedAxis.<anonymous closure> (package:flutter/src/rendering/debug.dart:337:13)
#1      debugCheckHasBoundedAxis (package:flutter/src/rendering/debug.dart:396:4)
#2      RenderViewport.computeDryLayout (package:flutter/src/rendering/viewport.dart:1384:12)
#3      RenderBox.performResize (package:flutter/src/rendering/box.dart:2668:12)
#4      RenderObject.layout (package:flutter/src/rendering/object.dart:2587:9)
#5      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#6      RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#7      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#8      RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#9      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#10     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#11     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#12     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#13     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#14     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#15     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#16     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#17     ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:61:11)
#18     RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:985:73)
#19     RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:1051:32)
#20     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#21     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:234:12)
#22     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#23     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:234:12)
#24     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#25     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:173:12)
#26     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1092:7)
#27     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:237:7)
#28     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:404:14)
#29     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#30     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#31     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#32     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#33     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1448:11)
#34     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#35     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#36     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#37     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#38     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#39     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#40     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#41     ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:61:11)
#42     RenderStack._computeSize (package:flutter/src/rendering/stack.dart:595:43)
#43     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:622:12)
#44     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#45     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#46     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#47     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#48     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#49     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#50     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#51     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#52     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#53     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#54     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#55     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#56     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3728:13)
#57     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#58     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#59     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#60     _RenderTheaterMixin.layoutChild (package:flutter/src/widgets/overlay.dart:1002:13)
#61     _RenderTheater.performLayout (package:flutter/src/widgets/overlay.dart:1311:9)
#62     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#63     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#64     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#65     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#66     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#67     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#68     RenderCustomPaint.performLayout (package:flutter/src/rendering/custom_paint.dart:569:11)
#69     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#70     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#71     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#72     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#73     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#74     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#75     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#76     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#77     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#78     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#79     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#80     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#81     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#82     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:21)
#83     RenderObject.layout (package:flutter/src/rendering/object.dart:2608:7)
#84     RenderView.performLayout (package:flutter/src/rendering/view.dart:281:14)
#85     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2446:7)
#87     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1065:15)
#88     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:602:23)
#89     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1164:13)
#90     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:468:5)
#91     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1397:15)
#92     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1318:9)
#93     SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:1040:9)
#94     PlatformDispatcher.scheduleWarmUpFrame.<anonymous closure> (dart:ui/platform_dispatcher.dart:837:16)
#98     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
(elided 3 frames from class _Timer and dart:async-patch)
 
The following RenderObject was being processed when the exception was fired: RenderViewport#d5613 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    needs compositing
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=398.0, 0.0<=h<=Infinity)
    size: MISSING
    axisDirection: down
    crossAxisDirection: right
    offset: ScrollPositionWithSingleContext#b7b6f(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#4402f, ScrollDirection.idle)
    anchor: 0.0
    center child: RenderSliverPadding#bbdeb NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        parentData: paintOffset=Offset(0.0, 0.0)
        constraints: MISSING
        geometry: null
        padding: EdgeInsets.zero
        textDirection: ltr
        child: RenderSliverList#ccfb1 NEEDS-LAYOUT NEEDS-PAINT
            parentData: paintOffset=Offset(0.0, 0.0)
            constraints: MISSING
            geometry: null
            no children current live
RenderObject: RenderViewport#d5613 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    needs compositing
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=398.0, 0.0<=h<=Infinity)
    size: MISSING
    axisDirection: down
    crossAxisDirection: right
    offset: ScrollPositionWithSingleContext#b7b6f(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#4402f, ScrollDirection.idle)
    anchor: 0.0
    center child: RenderSliverPadding#bbdeb NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        parentData: paintOffset=Offset(0.0, 0.0)
        constraints: MISSING
        geometry: null
        padding: EdgeInsets.zero
        textDirection: ltr
        child: RenderSliverList#ccfb1 NEEDS-LAYOUT NEEDS-PAINT
            parentData: paintOffset=Offset(0.0, 0.0)
            constraints: MISSING
            geometry: null
            no children current live
════════════════════════════════════════════════════════════════════════════════
 
════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderViewport#d5613 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 2164 pos 12: 'hasSize'
The relevant error-causing widget was:
    ListView ListView:file:///Users/ittae/development/ittae/lib/src/features/calendar/presentation/attendance_pages/widgets/attendance_result.dart:21:21
════════════════════════════════════════════════════════════════════════════════
 
I'll skip the several or dozens of RenderBox was not laid out errors that follow!

Identifying the Core of the Error Message#

While it's nice to look at every detail of the error message, most of the time the output comes from positions handled by the framework or SDK rather than the parts I developed. So even when I checked them one by one, it wasn't very helpful since I wasn't familiar with the framework source code.

Interpreting the log is a helpful way to easily identify the cause of an error. In long error logs, the first error message and the widget where it occurred are usually the most important parts. The long logs Flutter produces are typically the result of problems going through multiple rendering stages, and the first error that appears is most likely the core issue.

Rather than focusing on the entire output, you need to find a few important keywords. The main reason for errors in Flutter is that when you add or modify a widget, it's highly likely to be a layout-related issue.

Examining Error Types#

In my environment, looking at the debug console, some text is red and some is blue. Obviously, the red parts need closer attention. Reading the explanations before and after the red messages also helps solve the problem. Since the output is usually long and hard to take in all at once, taking time to examine the first error message is the fastest way to resolve the problem.

This error message appeared when I was using a ListView. ListView works fine in normal situations, but I had added a ListView as a child of a Column without specifying a size, so the height was infinite, causing the error.

image

Solutions#

Wrap the ListView that's a child of Column with Expanded

Expanded(
  child: ListView(
    children: [...],
  ),
)

Specify the height with a Container or SizedBox widget

SizedBox(
  height: 300.0, // desired height
  child: ListView(
    children: [...],
  ),
)

Add shrinkWrap: true to the ListView

ListView(
  shrinkWrap: true,
  children: [...],
)

Summary

  • Focus on the first error message at the top — most solutions can be found based on the first error
  • Track the widget and line number in the error message to pinpoint exactly where the problem occurred
  • Use Flutter official docs or Stack Overflow to find solutions for similar errors

Here and now...breathe and relax...in battle and in life.

— Dan Millman


Other posts
Recommended VS Code Extensions 커버 이미지
 ・ 5 min

Recommended VS Code Extensions

Introducing a Feature-First Architecture Example in Flutter 커버 이미지
 ・ 18 min

Introducing a Feature-First Architecture Example in Flutter

How to Fix a Downloaded Flutter Project That Won't Run 커버 이미지
 ・ 2 min

How to Fix a Downloaded Flutter Project That Won't Run