The infinite scroll trap
Putting a LazyColumn inside a vertically scrolling Column breaks layout. The book calls this the infinite scroll trap.

The trap is thinking you can nest a scrolling list inside a scrolling container. The book warns that a lazy list composes only what is visible, but a vertically scrolling Column composes every child. When you put a LazyColumn inside a Column with Modifier.verticalScroll, the parent hands the lazy list infinite height. Compose throws an error. The book calls this the infinite scroll trap.
The trap: nesting scrolling containers
Compose lays out in a single pass. A parent hands each child constraints (a minimum and maximum width and height), the child picks a size inside them, and the parent places it. Modifiers like size, fillMaxWidth, padding and widthIn simply change the constraints on the way down. When a layout looks wrong, ask: what constraints did this child receive? That question solves most layout puzzles faster than trial and error. The book explains this flow in one paragraph. The trap is that a parent offering infinite height to a child that cannot fill it causes a crash. The book shows a code example of a Column with Modifier.verticalScroll. It then warns: WATCH OUT Never put a LazyColumn inside a vertically scrolling Column (Modifier.verticalScroll). The lazy list would be offered infinite height and Compose throws an error.
The fix: move headers and footers into the list
The book states that a lazy list composes only what is visible and reuses the slots as you scroll. It also says that two details make lists behave: Keys and animateItem(). The fix is to put headers and footers inside the lazy list with item { } instead of nesting them. The book provides a code example of a PantryList composable. It uses a LazyColumn with a modifier and contentPadding. Inside the LazyColumn, it uses an item block for a header Text. Then it uses items(items = items, key = { it.id }) to render the list. The book calls this the correct approach and warns against nesting.
The fix: use Scaffold for the screen frame
The book introduces Scaffold as the Material 3 layout for a full screen. It has slots for a top bar, a bottom bar, a floating action button and a snackbar host, and it calculates the padding your content needs so nothing hides behind them or behind the system bars. The book shows a code example of a PantryListScreen composable. It uses @OptIn(ExperimentalMaterial3Api::class) and @Composable. It builds a Scaffold with a topBar, a floatingActionButton, and an innerPadding lambda. Inside the innerPadding, it calls PantryList and passes the innerPadding as contentPadding. The book warns: COMMON MISTAKE Ignoring the innerPadding lambda parameter. Android Studio warns you, and for good reason: without it, your first list item sits under the top bar and the last one under the navigation bar. Pass it to the content, and for lists pass it as contentPadding so the list can still scroll behind the bars while its first and last items stay visible.
The fix: use Material components for rows
The book suggests that for rows, reach for Material's ListItem before building your own Row. It gives you correct spacing and typography, with slots for a headline, supporting text and leading or trailing content. The book calls this a list row for free. It shows a code example of a ListItem composable. It sets headlineContent, supportingContent, and trailingContent. It also applies a modifier for clickability. The book mentions other ready-made pieces worth knowing: Card and ElevatedCard, HorizontalDivider, LazyVerticalGrid(GridCells.Adaptive(160.dp)) for grids that adapt to width, PullToRefreshBox around a list, and ModalBottomSheet.
Checklist
- Never put a LazyColumn inside a vertically scrolling Column
- Use item { } for headers and footers inside the list
- Use Scaffold for the screen frame
- Pass innerPadding as contentPadding to the content
- Use Material's ListItem for list rows

