Skip to content

CupertinoSheetRoute asserts when a drag ends in the frame a relayout lands #194681

Closed
flutter/packages
#13316

Description

@Shoezmann

Steps to reproduce

  1. Open a sheet built with showCupertinoSheet and scrollableBuilder, while the keyboard is up (non-zero view insets), so the sheet is laid out with a shorter height.
  2. Start a vertical drag on the sheet.
  3. Clear the view insets mid-drag (the keyboard dismissing).
  4. End the drag in the same frame as the relayout that follows.

The reproduction is from a shipping app that hit this twice on a physical device, both times with the keyboard leaving. I have not reduced it to a standalone test yet, so please treat step 4 as the condition rather than an exact recipe.

Actual results

The drag end throws:

Cannot get size from a render object that has been marked dirty for layout.
  _CupertinoDraggableScrollableSheetState._handleDragEnd  (cupertino/sheet.dart:1366)
  ← _CupertinoSheetScrollPosition.goBallistic ← ScrollDragController.end

In debug the throw then leaves the scroll state inconsistent: ScrollableState fails its _drag == null asserts at scrollable.dart:864 and :873, and the session is unrecoverable. In release the assert is stripped, so the read returns the last laid-out size and nothing cascades. The box in the failing frames was BoxConstraints(w=393, h=255.6) on an iPhone 14 Pro: laid out with the keyboard up, about to be re-laid out without it.

Expected results

No assert, and a stable velocity conversion: the sheet should remember the size it was laid out with, the way Scrollable keeps its metrics, instead of reading context.size from a gesture callback.

Analysis

_CupertinoDraggableScrollableSheetState reads context.size!.height in both _dragUpdate (cupertino/sheet.dart:1357) and _handleDragEnd (cupertino/sheet.dart:1366), and _CupertinoDragGestureDetectorState.sheetHeight does the same (:945, read from _handleDragUpdate and _handleDragEnd at :1002). context.size is Element.size, which throws when the render object is dirty for layout (framework.dart:5030), and the box it resolves to is the scrollableBuilder's root. Any relayout landing in the drag's last frame leaves that box dirty, so the read throws.

For contrast, the Material route reads renderBox.size at the same point in its own drag handling and has no such check.

Code sample

Minimal shape of the failing setup, rather than a runnable file:

showCupertinoSheet<void>(
  context: context,
  scrollableBuilder: (context, controller) => ListView(
    controller: controller,
    children: const <Widget>[SizedBox(height: 48, child: Text('row'))],
  ),
);
// With the keyboard up: press, drag, dismiss the keyboard mid-drag, release.

Flutter version

Flutter 3.47.7, stable, revision abaf9c5, engine d8a2d6c768c334d53e16277f837970ffa1e2de81.

Target: iPhone 14 Pro, iOS 27, debug build (the assert is debug-only).

Activity

  1. theprantadutta commented on Oct 19, 2026

    @theprantadutta
    Contributor

    I've opened flutter/packages#13316 with a fix. Both drag paths now read the height from the sheet's RenderBox instead of context.size. That's the last laid out size, which matches what release builds were already using. There's a regression test for each path, and both fail with this exact assertion without the fix.

    I couldn't reproduce the keyboard sequence itself in a widget test, so the tests set up the condition from your stack trace directly. If you're able to try the branch in your app, that would confirm it covers your case.

  2. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    team-designOwned by Design Languages team
    on Oct 19, 2026
  3. mbcorona commented on Oct 19, 2026

    @mbcorona
    Member

    Hi @Shoezmann, thanks for the report, and @theprantadutta for the PR. The context.size
    reads are there on master, this checks out. Routing to team-design.

  4. added
    p: cupertino_uicupertino_ui package in flutter/packages
    packageflutter/packages repository. See also p: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Oct 19, 2026
  5. added
    c: crashStack traces logged to the console
    P2Important issues not at the top of the work list
    triaged-designTriaged by Design Languages team
    on Oct 20, 2026
  6. added a commit that references this issue on Nov 11, 2026
    054d9d1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: crashStack traces logged to the consolep: cupertino_uicupertino_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions