skip to content

A Flutter boarding-gate card's Row shows a yellow-and-black stripe reading 'RIGHT OVERFLOWED BY 42 PIXELS'; how do you diagnose it from the constraints, and what ships in release?

level: seniorimportance: should knowfreq 48%

answer

  1. debug-only painted indicator
  2. RenderFlex constraints and size in the log
  3. unbounded main axis for non-flex children
  4. natural-size child is the culprit
  5. release paints past the edge

basics

~20 s

The overflow report names the RenderFlex, its constraints and size: non-flexible children, measured under the Row's unbounded main axis, took 42 pixels more than the Row's width. Release builds draw no stripe and paint past the edge.

solid answer

~50 s

The stripe comes from the overflow indicator, which is painted only in debug. The console reports 'A RenderFlex overflowed by 42 pixels on the right.' with the flex's `constraints`, its `size` and the widget that created it. I read that as: the card's Row got, say, `BoxConstraints(0.0<=w<=311.0)`, and its non-flexible children, each laid out with an unbounded main axis, reported natural widths summing to 353. Then I find the child with a fixed or natural width — a long gate-name `Text`, a `SizedBox(width: 120)` badge — and reproduce at narrow widths and large text scale. The fix follows from the constraints: give that child a bounded width it can shrink into (a flex factor), truncate or wrap text, scroll, or clip on purpose. In release there's no stripe and no log; with the default `Clip.none` the children simply paint past the card.

code

dart · 11 lines
dart
import 'package:flutter/material.dart';

// Overflows on narrow screens: every child keeps its natural width.
Widget gateRow(String gateName) => Row(
      children: [
        const Icon(Icons.flight_takeoff),
        Text(gateName, overflow: TextOverflow.ellipsis), // never truncates here
        const SizedBox(width: 120, child: Text('BOARDING')),
        const Text('10:45'),
      ],
    );

go deeper

for a junior

Recognise the stripe as content that does not fit its Row or Column, and know it is shown only in debug builds.

for a middle

Explain that non-flexible children are laid out with an unbounded main axis, so their natural widths add up past the Row's width.

for a senior

Diagnose from the reported constraints and size, reproduce at narrow widths and large text scales, decide which child must give way, and prevent silent release regressions with tests.

for a principal

Treat overflow as a product defect class: set review rules against fixed widths in rows and require narrow-width and large-text test coverage for card components.

## What the stripe is When a `Row` or `Column` lays out children whose total size along the main axis exceeds its own size, the underlying `RenderFlex` records an **overflow**. During paint it then does two things: - It paints its children through a clip call that honours `clipBehavior`, which defaults to `Clip.none` on `Flex`; `Row` and `Column` do not expose the parameter, so they always use that default. With `Clip.none` nothing is clipped. - Inside an `assert` block — so **only in debug builds** — it paints the **overflow indicator**: yellow-and-black stripes on the overflowing edge with a label such as `RIGHT OVERFLOWED BY 42 PIXELS`, and reports an error once, for example `A RenderFlex overflowed by 42 pixels on the right.` After a hot reload the report is issued again. The framework calls this an error condition because some content cannot be seen, even though the app keeps running. ## Reading the report The console message is more useful than the stripe. It contains: 1. **The creator** — the `Row` in your code that produced the `RenderFlex`, with its location in debug builds. 2. **The orientation** — horizontal for a `Row`. 3. **The RenderFlex's `constraints` and `size`** — for example `constraints: BoxConstraints(0.0<=w<=311.0, 0.0<=h<=Infinity)` and `size: Size(311.0, 56.0)`. 4. **Hints** — apply a flex factor, clip with `ClipRect`, or use a scrollable. The constraints tell you how much width the card gave the Row: 311 pixels. The overflow tells you the children asked for about 353. ## Why the children overflow The reason is the constraint rule applied to flex layout. A `RenderFlex` lays out every **non-flexible** child with an **unbounded main axis**: the child's max width is `double.infinity`. Such a child reports its **natural** width — the full width of a text run, the fixed width of a `SizedBox`, an icon's size — without regard to how much space the Row has. The Row adds those up after the fact, and if the sum exceeds its own width, it overflows. This also explains a common failed fix. Adding `overflow: TextOverflow.ellipsis` to the gate-name `Text` does nothing on its own: the text was measured under an unbounded width, so it never needs to truncate. Truncation starts working only once the text receives a bounded width. ## A diagnosis routine On the boarding-gate card, with an airline logo, a gate-name `Text`, a `SizedBox(width: 120)` status badge and a boarding-time `Text` in one `Row`: 1. **Read the Row's constraints** from the report. That is the budget, 311 pixels. 2. **List each child's natural width.** Fixed boxes are obvious; text depends on content and text scale. A gate name like a long terminal-and-gate string or a user's larger font setting is the usual culprit. 3. **Reproduce the worst case**: a narrow phone width, the longest realistic string and a large text scale (`TextScaler`). If it overflows only then, you have found a real device bug rather than a test artefact. 4. **Decide which child should give way.** One child must accept less than its natural width. That decision is the design, not the syntax. 5. **Apply the matching fix** and re-check at the worst case. | Situation | Fix driven by the constraints | |---|---| | One text child should shrink and truncate | give it a bounded width through a flex factor, then `maxLines: 1` and `TextOverflow.ellipsis` | | A fixed-width badge is too wide | size it from content or let it shrink; a hard-coded width ignores the budget | | Content is legitimately longer than the card | make the row scrollable or let it wrap | | Overflow is intended (a decorative bleed) | clip deliberately with `ClipRect`, or use `Flex` with a non-`none` `clipBehavior` (`Row` and `Column` do not expose it) | The flex-factor mechanics (`Expanded`, `Flexible`, fits) belong to the flex topic; here the point is that the diagnosis starts from constraints, not from trying wrappers until the stripe disappears. ## What release builds show The indicator painting and the error report live inside `assert` blocks, so **profile and release builds strip them**. The Row still overflows: with the default `Clip.none`, the children paint past the card's right edge, possibly over neighbouring content, or get cut by some ancestor's clip. Nothing is logged. An overflow you ignored in debug therefore ships silently. That is why teams keep widget tests at narrow sizes and large text scales; in `flutter_test` the reported overflow error fails the test. ## What not to do - Do not wrap the Row in `ClipRect` just to hide the stripe; the information is still cut off. - Do not hard-code a smaller width that fits one device. - Do not treat the stripe as a debug-only cosmetic: it describes content users cannot see.

  • Why doesn't TextOverflow.ellipsis on a Text inside a Row stop the overflow?
    A `Row` lays out a non-flexible `Text` with an unbounded width, so the text measures at its full natural width and never needs to truncate. Ellipsis applies only when the text's max width is smaller than its content. The text must first receive a bounded width, typically by giving it a flex factor in the Row, and then `maxLines: 1` with `TextOverflow.ellipsis` works.
  • The overflow appears only on one tester's phone; what do you check first?
    The two inputs that change natural sizes: the screen width, which sets the Row's constraints, and the text scale from the user's font settings, which makes every `Text` wider. Reproduce with the narrowest supported width, the longest realistic gate name and a large text scale, then fix the layout for that case rather than for your own device.

saying these in an interview costs you the question

  • The stripe also shows in release, so users will report it.
  • Adding TextOverflow.ellipsis to the Text is enough to fix a Row overflow.
  • Wrapping the Row in ClipRect solves the overflow.
  • The overflow is harmless because it is only a debug warning.
  • A RenderFlex overflow means the Row itself received unbounded constraints.