Fix SplitPane RangeError when child count changes between rebuilds#9822
Conversation
Fixes flutter#9648. SplitPane cached its fractions list in initState only. When the parent rebuilt the widget with a different number of children (for example, toggling a panel via a collection-if), fractions.length stayed at the old value while widget.minSizes and widget.children shrank, causing minSizeForIndex to read past the end of widget.minSizes and throw 'RangeError (index): Index out of range: index should be less than 2: 2' from the layout pass. This adds didUpdateWidget to _SplitPaneState. When the child count changes, fractions is reset to List.of(widget.initialFractions) so it stays in sync with the new children and minSizes. The existing constructor assertion already guarantees children.length matches initialFractions.length. Bumps devtools_app_shared to 0.5.2 with a CHANGELOG entry, and adds regression tests that pump a 3-child SplitPane and then a 2-child SplitPane (and vice versa) and assert no exception is thrown.
There was a problem hiding this comment.
Code Review
This pull request addresses a RangeError in the SplitPane widget triggered by changes in the number of children during rebuilds. The fix modifies _SplitPaneState to reset the fractions list within didUpdateWidget whenever the child count changes. The devtools_app_shared package version is updated to 0.5.2, and new tests are included to ensure stability when the number of children grows or shrinks. I have no feedback to provide.
kenzieschmoll
left a comment
There was a problem hiding this comment.
please add a release note entry for this change.
|
@kenzieschmoll yeah calling a RangeError 'not user facing' was a stretch on my part 😅. Added a General updates entry and corrected the PR body. Pushed. |
kenzieschmoll
left a comment
There was a problem hiding this comment.
LGTM with a couple more comments regarding the version of devtools_app_shared
|
@kenzieschmoll Both bumped to |
Fixes #9648.
SplitPanecached itsfractionslist ininitStateonly. When the parent rebuilt the widget with a different number of children (for example, toggling a panel in or out with a collection-if),fractions.lengthstayed at the old value whilewidget.minSizesandwidget.childrenshrank. The next layout pass calledminSizeForIndexwith an index past the end ofwidget.minSizesand threwRangeError (index): Index out of range: index should be less than 2: 2fromsplit_pane.dart:126.This adds
didUpdateWidgetto_SplitPaneState. When the child count changes,fractionsis reset toList.of(widget.initialFractions)so it stays in sync with the newchildrenandminSizes. The existing constructor assertion (children.length == initialFractions.length) already guarantees the new list has the right length, so no extra defensive logic is needed.fractionslost itsfinalmodifier to allow the reassignment.devtools_app_sharedis bumped to0.5.2and a CHANGELOG entry is added.Tests
Added two regression tests in
split_pane_test.dartunder a newrebuilds with a different number of childrengroup:SplitPane, then pumps a 2-childSplitPanewith the same key path, and asserts no exception is thrownBoth tests reproduce the original
RangeErroron master and pass with the fix.Note: running the local
flutter testagainst the bundled Flutter SDK currently fails to compile because of an unrelated pre-existing error influtter/lib/src/widgets/_window_linux.dart(isSizedToContentgetter is missing onWindowingOwnerLinux). That failure reproduces on master without this change and is independent ofSplitPane. CI should compile against a matching SDK.Pre-launch Checklist
General checklist
///).Issues checklist
contributions-welcomeorgood-first-issuelabel.contributions-welcomeorgood-first-issuelabel. I understand this means my PR might take longer to be reviewed.Tests checklist
AI-tooling checklist
Feature-change checklist
release-notes-not-requiredlabel or left a comment requesting the label be added.packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.If you need help, consider asking for help on Discord.