How to Fix Flutter RenderFlex Overflow and Unbounded Height Errors

Wrap scrollable widgets like ListView in Expanded or Flexible to constrain their dimensions within Column or Row parents, and use Expanded on text widgets inside Row to prevent overflow.

Flutter’s layout engine follows the rule “constraints go down, sizes go up, parents set position.” When this contract is violated, the framework throws “RenderFlex overflowed” or “Vertical viewport was given unbounded height” errors. The flutter/skills repository codifies a systematic fix workflow in the flutter-fix-layout-issues skill.

Understanding the Layout Contract

According to the diagnostic checklist in skills/flutter-fix-layout-issues/SKILL.md, every Flutter layout error stems from a constraint violation. Parents pass tight or loose constraints down the tree, children report their sizes back up, and parents finalize positions. Breaking this flow—such as placing an infinitely tall ListView inside a Column that lacks intrinsic height—triggers unbounded height errors.

The Diagnostic Workflow

The skill mandates a two-step checklist before applying fixes:

  1. Isolate the primary error – Ignore secondary “RenderBox was not laid out” cascades that pollute the console.
  2. Match the signature – Map the root error to one of four conditional fixes based on widget type and parent.

Fixing Unbounded Height Errors

Unbounded height occurs when a scrollable widget resides inside a Column without explicit dimensional constraints. The flutter/skills documentation recommends wrapping the offender in Expanded to force it to occupy remaining space.

// Before: Throws "Vertical viewport was given unbounded height"
Column(
  children: <Widget>[
    const Text('Header'),
    ListView(
      children: const <Widget>[
        ListTile(title: Text('Item 1')),
        ListTile(title: Text('Item 2')),
      ],
    ),
  ],
)
// After: ListView constrained within Column
Column(
  children: <Widget>[
    const Text('Header'),
    Expanded(
      child: ListView(
        children: const <Widget>[
          ListTile(title: Text('Item 1')),
          ListTile(title: Text('Item 2')),
        ],
      ),
    ),
  ],
)

Alternatively, wrap the scrollable in a SizedBox with explicit height when flexible expansion is undesirable.

Fixing Unbounded Width Errors

Horizontal analogs appear when input widgets like TextField sit inside Row containers. Because TextField attempts to expand infinitely to accommodate input, it violates the Row’s bounded width constraint.

// Before: Throws "An InputDecorator...cannot have an unbounded width"
Row(
  children: [
    const Icon(Icons.search),
    TextField(),
  ],
)
// After: TextField constrained via Expanded
Row(
  children: [
    const Icon(Icons.search),
    Expanded(
      child: TextField(),
    ),
  ],
)

Fixing RenderFlex Overflow

RenderFlex overflow manifests when children collectively exceed the available cross-axis space. As implemented in the flutter/skills guidance, use Expanded or Flexible with fit: FlexFit.loose to force the child to respect the parent’s bounds.

// Before: Throws "RenderFlex overflowed by X pixels"
Row(
  children: [
    const Icon(Icons.info),
    const Text(
        'This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
  ],
)
// After: Text wraps within constraints using Expanded
Row(
  children: [
    const Icon(Icons.info),
    Expanded(
      child: const Text(
          'This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
    ),
  ],
)

Common Anti-Patterns and ParentData Issues

The skill file warns against Incorrect ParentData usage. Widgets like Expanded, Flexible, and Positioned must be direct children of their required parents (Row, Column, or Stack). Nesting an Expanded inside a Container that is not itself inside a flex parent violates the ParentData contract and throws runtime assertions.

After applying any fix, perform a hot-reload and verify that yellow/black overflow stripes disappear from the UI. If new warnings surface, repeat the diagnostic workflow.

Summary

  • Unbounded height in Column → Wrap ListView or SingleChildScrollView in Expanded or give fixed SizedBox height.
  • Unbounded width in Row → Wrap TextField or long text in Expanded to constrain horizontal expansion.
  • RenderFlex overflow → Apply Expanded or Flexible with fit: FlexFit.loose to offending children.
  • ParentData violations → Ensure Expanded/Flexible are immediate children of Row/Column/Stack.
  • Always isolate the primary error before fixing secondary cascades, as outlined in flutter/skills.

Frequently Asked Questions

What causes unbounded height errors in Flutter?

Unbounded height errors occur when a scrollable widget attempts to shrink-wrap its content while its parent (Column or ListView) provides no intrinsic height constraint. According to the flutter/skills documentation, this breaks the "constraints go down" contract because the child receives an infinite vertical constraint from the viewport but the parent cannot resolve a finite size.

When should I use Expanded versus Flexible to fix overflow?

Use Expanded when you want the child to fill all remaining space in the flex container. Use Flexible with fit: FlexFit.loose when the child should size to its intrinsic dimensions but still respect the container’s bounds, preventing overflow without forcing maximum expansion.

Why does RenderFlex overflow happen inside a Column but not a ListView?

Column measures its children against the maximum available cross-axis space without bounding them, whereas ListView builds children lazily within a defined viewport. When a Text widget inside a Row (within a Column) exceeds screen width, the Row cannot automatically wrap or scroll, triggering the overflow error.

Can I nest a ListView inside another ListView without using Expanded?

Yes, but only if the outer ListView provides a bounded constraint to the inner one. If the outer scrollable is inside a Column, you must wrap it in Expanded or SizedBox to give it a defined height, otherwise the inner ListView will trigger an unbounded height assertion.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →