Sitelet https://github.com/flutter/flutter/pull/186993
Skip to content

Fix NestedScrollView example crash when switching tabs on desktop - #186993

Merged
auto-submit[bot] merged 2 commits into
flutter:masterfrom
gabrimatic:fix-nested-scrollbar-multiple-positions
Jul 29, 2026
Merged

auto-submit[bot] merged 2 commits into
flutter:masterfrom
gabrimatic:fix-nested-scrollbar-multiple-positions

Conversation

@gabrimatic

@gabrimatic gabrimatic commented May 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #183199

The NestedScrollView API example that uses a TabBar/TabBarView throws on desktop when you scroll an inner list and then switch tabs. The inner CustomScrollViews are coordinated by the NestedScrollView through a shared controller, which can be attached to more than one ScrollPosition at a time (for example mid-transition between tabs). The automatic desktop scrollbar attaches to that shared controller, and a single scrollbar cannot represent multiple positions, so RawScrollbar throws the multiple-position assertion.

This leaves the framework unchanged and fixes the example itself: the TabBarView body is wrapped in a ScrollConfiguration that disables the default scrollbars, since a single scrollbar cannot correctly represent the coordinated inner positions. A regression test reproduces the exact assertion from the issue (scroll, then a mouse-wheel pointer signal during a tab transition) and confirms it no longer throws.

Tests

  • flutter test examples/api/test/widgets/nested_scroll_view/nested_scroll_view.0_test.dart
  • flutter analyze examples/api/lib/widgets/nested_scroll_view/nested_scroll_view.0.dart examples/api/test/widgets/nested_scroll_view/nested_scroll_view.0_test.dart

Pre-launch Checklist

@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels May 23, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies NestedScrollView to wrap its body in a ScrollConfiguration that disables automatic scrollbars, and adds a corresponding regression test for desktop platforms. Feedback suggests ensuring that any custom scrollBehavior provided to the NestedScrollView is respected by prioritizing it over the context-based ScrollConfiguration when disabling scrollbars.

Comment thread packages/flutter/lib/src/widgets/nested_scroll_view.dart Outdated
@Piinks
Piinks self-requested a review June 2, 2026 22:19

@Piinks Piinks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @gabrimatic thanks for sending another PR. I am not sure this is the right solution to the reported problem.

NestedScrollView already removes default scrollbars from its outer scroll view because it cannot infer whether the nested scroll positions should be decorated as one scrollable or separate scrollables.

This is not exactly true. Scrollbars are disabled on the outer scrollable so that there are not two duplicate scrollbars in a nested scroll view.
Removing scrollbars entirely prevents the crash, but does not solve the actual problem. If someone applies a scrollbar manually, it will still be able to trigger the crash that was reported in the issue. Is there another way to solve the issue?

@gabrimatic

Copy link
Copy Markdown
Contributor Author

Updated this to cover the manual scrollbar path too. The fix now lets scrollbars that implicitly use a shared PrimaryScrollController paint from their accepted ScrollNotifications while keeping drag/track gestures disabled when more than one position is attached, so a manual Scrollbar around NestedScrollView inner scrollables no longer hits the multiple-position assertion.\n\nLocal checks passed:\n- ../../bin/flutter test --no-pub test/widgets/nested_scroll_view_test.dart\n- ../../bin/flutter test --no-pub test/widgets/scrollbar_test.dart\n- ../../bin/flutter analyze --no-pub lib/src/widgets/scrollbar.dart lib/src/widgets/nested_scroll_view.dart test/widgets/nested_scroll_view_test.dart\n- git diff --check

@Piinks
Piinks self-requested a review June 23, 2026 22:33

@Piinks Piinks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. However, modifying RawScrollbar to accommodate multiple positions is not something we want to do:

A single scrollbar cannot correctly represent or control multiple scroll positions. The thumb will jump erratically if multiple lists scroll (e.g. during transitions), and because gestures are disabled when positions.length > 1 , it creates a dead/non-interactive scrollbar.

If a user hovers and scrolls a mouse wheel over the scrollbar track, it triggers _receivedPointerSignal which calls _cachedController!.position . Since multiple positions are attached, this will crash the application.

On desktop, the framework's ScrollBehavior.buildScrollbar explicitly passes controller: details.controller to Scrollbar. Because the controller is not null, tryPrimary remains false and the automatic scrollbars will still throw the multiple-positions assertion.

Since the goal of this PR is to fix the crash in the NestedScrollView sample code, maybe we should focus on that instead.

@gabrimatic
gabrimatic force-pushed the fix-nested-scrollbar-multiple-positions branch from 252e435 to 0a49a15 Compare July 14, 2026 21:54
@gabrimatic

Copy link
Copy Markdown
Contributor Author

Thanks @Piinks — agreed on all three points. I've reverted the RawScrollbar changes, so scrollbar.dart is back to its original state, and narrowed the PR to just the sample fix.

NestedScrollView now applies the same no-default-scrollbar treatment to its body that the outer scrollable already gets, so the automatic desktop scrollbar no longer attaches to the coordinated inner controller. Manual Scrollbars over multiple inner positions are left out of scope, since a single scrollbar can't meaningfully represent more than one position.

Verified locally against the issue's sample: reproduced the exact _debugCheckHasValidScrollPosition assertion with a desktop pointer-scroll during a tab transition (two positions attached), confirmed it's gone with the fix, and the full nested_scroll_view_test.dart suite + flutter analyze pass.

@Piinks

Piinks commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

NestedScrollView now applies the same no-default-scrollbar treatment to its body that the outer scrollable already gets, so the automatic desktop scrollbar no longer attaches to the coordinated inner controller. Manual Scrollbars over multiple inner positions are left out of scope, since a single scrollbar can't meaningfully represent more than one position.

Again, this is not a change we want to make. Disabling scrollbars on the inner scrollable in NestedScrollView is not the correct fix here. This breaks the current expected default behavior.

@gabrimatic
gabrimatic force-pushed the fix-nested-scrollbar-multiple-positions branch from 0a49a15 to 262662b Compare July 14, 2026 22:56
@gabrimatic gabrimatic changed the title Disable default scrollbars for NestedScrollView bodies Fix NestedScrollView example crash when switching tabs on desktop Jul 14, 2026
@gabrimatic

Copy link
Copy Markdown
Contributor Author

You're right, thanks for your patience here. I've taken the fix out of the framework entirely.

scrollbar.dart and nested_scroll_view.dart are back to master (no framework changes at all now). The fix lives in the example that actually throws (nested_scroll_view.0.dart): the TabBarView body is wrapped in a ScrollConfiguration that disables the default scrollbars, since the inner views share the NestedScrollView's coordinated controller and a single scrollbar can't represent more than one position.

I also added a regression test on TargetPlatformVariant.desktop() that reproduces the exact assertion from the issue (scroll the inner list, then a mouse-wheel pointer signal during a tab transition) and confirms it no longer throws. Verified it fails on the unpatched sample and passes with the fix; flutter analyze and the example test suite are green.

@github-actions github-actions Bot added d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos labels Jul 14, 2026
@gabrimatic
gabrimatic force-pushed the fix-nested-scrollbar-multiple-positions branch from 262662b to b69580d Compare July 15, 2026 07:54
@gabrimatic
gabrimatic requested a review from Piinks July 15, 2026 14:46

@Piinks Piinks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates

Comment thread examples/api/lib/widgets/nested_scroll_view/nested_scroll_view.0.dart Outdated
@gabrimatic
gabrimatic requested a review from Piinks July 22, 2026 10:35

@Piinks Piinks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Piinks
Piinks force-pushed the fix-nested-scrollbar-multiple-positions branch from 1c9f99d to 8004ee1 Compare July 28, 2026 21:48
@Piinks Piinks added the CICD Run CI/CD label Jul 28, 2026
@AbdeMohlbi AbdeMohlbi added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 29, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Jul 29, 2026
Merged via the queue into flutter:master with commit abb7f63 Jul 29, 2026
28 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 29, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Aug 8, 2026
…12393)

Manual roll requested by stuartmorgan@google.com

flutter/flutter@2a230d1...2757a77

2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 3ae9e364d30b to 0f35bba4945c (2 revisions) (flutter/flutter#190215)
2026-07-29 kustermann@google.com [web] Fix deferred loading with wasm (flutter/flutter#190140)
2026-07-29 engine-flutter-autoroll@skia.org Roll Dart SDK from 1bbaacba6a5a to 43f7de5f4977 (1 revision) (flutter/flutter#190211)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 119cae396625 to 3ae9e364d30b (6 revisions) (flutter/flutter#190208)
2026-07-29 matej.knopp@gmail.com [Win32] Ignore mouse move events without capture when dragging (flutter/flutter#190029)
2026-07-29 engine-flutter-autoroll@skia.org Roll Dart SDK from 49c637261348 to 1bbaacba6a5a (7 revisions) (flutter/flutter#190196)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 30ad01017a46 to 119cae396625 (2 revisions) (flutter/flutter#190183)
2026-07-29 46920873+gabrimatic@users.noreply.github.com Fix NestedScrollView example crash when switching tabs on desktop (flutter/flutter#186993)
2026-07-29 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from OZkZC_2CZ_G5rbMIS... to J8rVTlBnjnUpuHYk3... (flutter/flutter#190174)
2026-07-29 git@schultek.dev Update widget location tracking to use the new generalized api (flutter/flutter#189725)
2026-07-29 bernaferrari2@gmail.com Avoid unnecessary work in `BoxDecoration` and `RenderPhysicalModel` (flutter/flutter#187891)
2026-07-29 me@davidmiguel.com Fix web context-menu client lifecycle in SelectableRegion (flutter/flutter#189587)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 70733f74d415 to 30ad01017a46 (2 revisions) (flutter/flutter#190173)
2026-07-29 jason-simmons@users.noreply.github.com Manual roll of Dart from 28e63ac22d8d to 49c637261348 (flutter/flutter#190158)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NestedScrollView example throws error

3 participants