Description
On web with classic (non-overlay) scrollbars — i.e. Windows/Linux Chrome and macOS with "Always show scroll bars", FlashList v2 can enter an infinite layout loop and crash with Maximum update depth exceeded because the vertical scrollbar's own appearance/disappearance feeds back into the list's cross-axis (width) measurement.
When list content height sits right at the threshold where it just barely overflows the viewport, the browser shows a vertical scrollbar. The scrollbar consumes ~15–17px of width, which reduces the measured client width FlashList uses as boundedSize. The narrower width re-flows items so the content no longer overflows → the scrollbar is removed → the measured width grows back → content overflows again → the scrollbar returns → and so on, forever.
This is web-specific: native platforms use overlay scrollbars that don't consume layout width, so they never oscillate.
Current behavior
- The list rapidly re-lays-out, the scrollbar visibly flickers, and React throws
Maximum update depth exceeded (setState loop in updateLayoutParams → recompute layout → measure → updateLayoutParams …), crashing the app.
- Happens whenever content size is near the boundary at which adding/removing the scrollbar flips whether the content overflows.
Expected behavior
FlashList should not let the scrollbar's own width feedback-loop the layout.
Reproduction
Expo Snack or minimal reproduction link:
Make sure to test on web with classic (non-overlay) scrollbar. If you use MacOS fo to Settings -> Appearance -> Windows -> Show scroll bars -> Always.
https://snack.expo.dev/@vikstash/flashlist_loop_crash
Platform
Environment
React Native info output:
FlashList version:
2.3.0
Additional context
Root cause is in LinearLayoutManager.ts, method updateLayoutParams. boundedSize is taken directly from the measured window size with no detection of scrollbar-induced oscillation, so the scrollbar appearing/disappearing keeps changing the measured width and re-triggering layout.
Checklist
Description
On web with classic (non-overlay) scrollbars — i.e. Windows/Linux Chrome and macOS with "Always show scroll bars", FlashList v2 can enter an infinite layout loop and crash with
Maximum update depth exceededbecause the vertical scrollbar's own appearance/disappearance feeds back into the list's cross-axis (width) measurement.When list content height sits right at the threshold where it just barely overflows the viewport, the browser shows a vertical scrollbar. The scrollbar consumes ~15–17px of width, which reduces the measured client width FlashList uses as boundedSize. The narrower width re-flows items so the content no longer overflows → the scrollbar is removed → the measured width grows back → content overflows again → the scrollbar returns → and so on, forever.
This is web-specific: native platforms use overlay scrollbars that don't consume layout width, so they never oscillate.
Current behavior
Maximum update depth exceeded(setStateloop inupdateLayoutParams→ recompute layout → measure →updateLayoutParams…), crashing the app.Expected behavior
FlashList should not let the scrollbar's own width feedback-loop the layout.
Reproduction
Expo Snack or minimal reproduction link:
Make sure to test on web with classic (non-overlay) scrollbar. If you use MacOS fo to Settings -> Appearance -> Windows -> Show scroll bars -> Always.
https://snack.expo.dev/@vikstash/flashlist_loop_crash
Platform
Environment
React Native info output:
FlashList version:
2.3.0
Additional context
Root cause is in
LinearLayoutManager.ts, methodupdateLayoutParams.boundedSizeis taken directly from the measured window size with no detection of scrollbar-induced oscillation, so the scrollbar appearing/disappearing keeps changing the measured width and re-triggering layout.Checklist