Skip to content

[GoRouter] and CupertinoSheetRoute doesn't work correctly together. CupertinoSheetRoute always uses root navigator to pop. #172010

Closed

Description

@Greatest4Ce

Steps to reproduce

  • Create an app with GoRouter using StatefulShellRoute;
  • Push from one of StatefulShellBranche's to CupretinoSheetRoute;
  • Try to close pushed route.

Expected results

Pushed route will be closed without problem.

Actual results

CupertinoSheetRoute uses root navigator and pops entire stack of pages.

Code sample

Code sample
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(const MyApp());
}

class _CustomPage<T> extends Page<T> {
  final Widget child;

  const _CustomPage(
      {super.key,
      super.name,
      super.arguments,
      super.restorationId,
      super.canPop,
      super.onPopInvoked,
      required this.child});

  @override
  Route<T> createRoute(BuildContext context) => CupertinoSheetRoute<T>(
        settings: this,
        builder: (context) => child,
      );
}

class _ShellBuilder extends StatelessWidget {
  const _ShellBuilder({required this.navigationShell});

  final StatefulNavigationShell navigationShell;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: navigationShell,
      bottomNavigationBar: BottomNavigationBar(
        onTap: (index) => navigationShell.goBranch(index),
        selectedItemColor: Colors.green,
        selectedLabelStyle: TextStyle(color: Colors.green),
        currentIndex: navigationShell.currentIndex,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'home'),
          BottomNavigationBarItem(icon: Icon(Icons.man), label: 'user'),
        ],
      ),
    );
  }
}

class _HomePage extends StatelessWidget {
  const _HomePage();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(
          'home',
          style: TextStyle(color: Colors.black),
        ),
      ),
    );
  }
}

class _UserPage extends StatelessWidget {
  const _UserPage();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          onPressed: () => context.push('/user/pushedRoute'),
          child: Text(
            'pushToRoute',
            style: TextStyle(color: Colors.black),
          ),
        ),
      ),
    );
  }
}

class _PushedRoute extends StatelessWidget {
  const _PushedRoute();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('pushedRoute'),
      ),
    );
  }
}

abstract class _Router {
  static final router = GoRouter(
    debugLogDiagnostics: true,
    initialLocation: '/user',
    routes: [
      StatefulShellRoute.indexedStack(
        branches: [
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/home',
                builder: (context, state) => _HomePage(),
              ),
            ],
          ),
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/user',
                builder: (context, state) => _UserPage(),
                routes: [
                  GoRoute(
                    path: '/pushedRoute',
                    pageBuilder: (context, state) =>
                        _CustomPage<void>(child: _PushedRoute()),
                  )
                ],
              ),
            ],
          ),
        ],
        builder: (context, state, navigationShell) =>
            _ShellBuilder(navigationShell: navigationShell),
      ),
    ],
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _Router.router,
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration https://github.com/user-attachments/assets/c2d4fc31-30b1-474b-a535-59adf37ec691

Logs

Logs
[GoRouter] Full paths for routes:
           └─ (ShellRoute)
             ├─/home (_HomePage)
             └─/user (_UserPage)
               └─/user/pushedRoute
[GoRouter] setting initial location /user
2
[GoRouter] Using MaterialApp configuration
[GoRouter] pushing /user/pushedRoute

════════ Exception caught by gesture ═══════════════════════════════════════════
The following assertion was thrown while handling a gesture:
You have popped the last page off of the stack, there are no pages left to show
'package:go_router/src/delegate.dart':
Failed assertion: line 169 pos 7: 'currentConfiguration.isNotEmpty'

When the exception was thrown, this was the stack:
#2      GoRouterDelegate._debugAssertMatchListNotEmpty (package:go_router/src/delegate.dart:169:7)
delegate.dart:169
#3      GoRouterDelegate._completeRouteMatch (package:go_router/src/delegate.dart:190:5)
delegate.dart:190
#4      GoRouterDelegate._handlePopPageWithRouteMatch (package:go_router/src/delegate.dart:148:7)
delegate.dart:148
#5      _CustomNavigatorState._handlePopPage (package:go_router/src/builder.dart:427:42)
builder.dart:427
#6      NavigatorState.pop (package:flutter/src/widgets/navigator.dart:5580:28)
navigator.dart:5580
#7      _CupertinoDownGestureController.dragEnd (package:flutter/src/cupertino/sheet.dart:798:23)
sheet.dart:798
#8      _CupertinoDownGestureDetectorState._handleDragEnd (package:flutter/src/cupertino/sheet.dart:707:29)
sheet.dart:707
#9      DragGestureRecognizer._checkEnd.<anonymous closure> (package:flutter/src/gestures/monodrag.dart:897:47)
monodrag.dart:897
#10     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
recognizer.dart:345
#11     DragGestureRecognizer._checkEnd (package:flutter/src/gestures/monodrag.dart:897:5)
monodrag.dart:897
#12     DragGestureRecognizer.didStopTrackingLastPointer (package:flutter/src/gestures/monodrag.dart:764:9)
monodrag.dart:764
#13     OneSequenceGestureRecognizer.stopTrackingPointer (package:flutter/src/gestures/recognizer.dart:540:9)
recognizer.dart:540
#14     DragGestureRecognizer._giveUpPointer (package:flutter/src/gestures/monodrag.dart:773:5)
monodrag.dart:773
#15     DragGestureRecognizer.handleEvent (package:flutter/src/gestures/monodrag.dart:725:7)
monodrag.dart:725
#16     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:97:12)
pointer_router.dart:97
#17     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
pointer_router.dart:143
#18     _LinkedHashMapMixin.forEach (dart:_compact_hash:764:13)
#19     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
pointer_router.dart:141
#20     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:131:7)
pointer_router.dart:131
#21     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:530:19)
binding.dart:530
#22     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:499:22)
binding.dart:499
#23     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:473:11)
binding.dart:473
#24     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:437:7)
binding.dart:437
#25     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:394:5)
binding.dart:394
#26     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:341:7)
binding.dart:341
#27     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:308:9)
binding.dart:308
#28     _invoke1 (dart:ui/hooks.dart:347:13)
hooks.dart:347
#29     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:467:7)
platform_dispatcher.dart:467
#30     _dispatchPointerDataPacket (dart:ui/hooks.dart:282:31)
hooks.dart:282
(elided 2 frames from class _AssertionError)

Handler: "onEnd"

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.32.6, on macOS 15.3.2 24D81 darwin-arm64, locale en-RU) [314ms]
    • Flutter version 3.32.6 on channel stable at /Users/karimsultanbekov/fvm/versions/3.32.6
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 077b4a4ce1 (3 days ago), 2025-07-08 13:31:08 -0700
    • Engine revision 72f2b18bb0
    • Dart version 3.8.1
    • DevTools version 2.45.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [989ms]
    • Android SDK at /Users/karimsultanbekov/Library/Android/sdk
    • Platform android-35, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.4) [576ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16F6
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [64ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3) [63ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] IntelliJ IDEA Ultimate Edition (version 2024.2.3) [62ms]
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 82.1.3
    • Dart plugin version 242.22855.32

[✓] VS Code (version 1.95.3) [6ms]
    • VS Code at /Users/karimsultanbekov/Downloads/Visual Studio Code.app/Contents
    • Flutter extension version 3.114.0

[✓] Network resources [332ms]
    • All expected network resources are available.

• No issues found!

Activity

  1. Greatest4Ce commented on Jul 11, 2025

    @Greatest4Ce
    Author

    Recorded video

    Screenshots / Video demonstration
    Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-07-11.at.20.04.08.mp4
  2. Greatest4Ce commented on Jul 11, 2025

    @Greatest4Ce
    Author

    For me it seems like problem is in this lines of 'flutter/lib/src/cupertino/sheet.dart' lines 795-799.

    ...
    if (isCurrent) {
            // This route is destined to pop at this point. Reuse navigator's pop.
            final NavigatorState rootNavigator = Navigator.of(navigator.context, rootNavigator: true);
            rootNavigator.pop();
          }
    ...
  3. Greatest4Ce commented on Jul 11, 2025

    @Greatest4Ce
    Author

    Error:

    _AssertionError ('package:go_router/src/delegate.dart': Failed assertion: line 169 pos 7: 'currentConfiguration.isNotEmpty': You have popped the last page off of the stack, there are no pages left to show)

  4. darshankawar commented on Jul 14, 2025

    @darshankawar
    Member

    @Greatest4Ce Thanks for the report. Based on the error log, it seems similar to #142678 for which the reasoning of closure is: #142678 (comment), so please check if it helps further in your case or not.

  5. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 14, 2025
  6. Greatest4Ce commented on Jul 14, 2025

    @Greatest4Ce
    Author

    @darshankawar Thanks for your answer. Yeah, issue #142678 seems familiar, I read it and tried given solutions, but found that it's not my situation. Author tries to close BottomSheetRoute by "his hands" and he navigates to it by showDialog() or showBottomSheet() methods.
    Differences of my case:

    • I close BottomSheetRoute by swipe that executes CupertinoSheetRoute's "inbox" close logic.
    • I don't use showBottomSheet() method and push to it by GoRouter's context.push().

    And I found that ModalBottomSheetRoute's (I use it for Android UX, pls tell me if I wrong) logic works correctly:

    code from flutter/lib/src/material/bottom_sheet.dart lines 722-726

    ...
             onClosing: () {
              if (widget.route.isCurrent) {
                Navigator.pop(context);
              }
            },
    ...
  7. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 14, 2025
  8. Greatest4Ce commented on Jul 14, 2025

    @Greatest4Ce
    Author

    For me I found solution in creating GlobalKey for GoRouter and pass it like this:

    ....
    final _mainRouter = GlobalKey<NavigatorState>();
    ...
    static final router = GoRouter(
    navigatorKey: _mainRouter,
    ...
    StatefulShellBranch(
                routes: [
                  GoRoute(
                    path: '/user',
                    builder: (context, state) => _UserPage(),
                    routes: [
                      GoRoute(
                        path: '/pushedRoute',
                        parentNavigatorKey: _mainRouter,
                        pageBuilder: (context, state) =>
                            _CustomPage<void>(child: _PushedRoute()),
                      )
                    ],
                  ),
                ],
              ),
    ....

    In this case new route pushing to main router and everything works correctly. But in case then a want to push this route to nested ShellRoute's navigator CupertinoSheetRoute always pop's rootNavigator.

  9. darshankawar commented on Jul 15, 2025

    @darshankawar
    Member

    Thanks for the update. I was able to replicate the reported behavior. Keeping the issue open for team's tracking.

    stable : 3.32.6
    master : 3.33.0-1.0.pre-970
    
  10. added
    packageflutter/packages repository. See also p: labels.
    p: cupertino_uicupertino_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    on Jul 15, 2025
  11. 1 remaining item

  12. added
    f: routesNavigator, Router, and related APIs.
    and removed
    in triagePresently being triaged by the triage team
    on Jul 15, 2025
  13. added
    P3Issues that are less important to the Flutter project
    workaround availableThere is a workaround available to overcome the issue
    on Jul 15, 2025
  14. added a commit that references this issue on Sep 4, 2025
    8b6d1da
  15. added
    r: fixedIssue is closed as already fixed in a newer version
    on Sep 5, 2025
  16. added a commit that references this issue on Sep 18, 2025
    92bd83e
  17. github-actions commented on Sep 19, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  18. locked as resolved and limited conversation to collaborators on Sep 19, 2025
  19. added a commit that references this issue on Sep 24, 2025
    1d1127f
  20. added a commit that references this issue on Nov 21, 2025
    d1f9302
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

    P3Issues that are less important to the Flutter projectf: routesNavigator, Router, and related APIs.found in release: 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: cupertino_uicupertino_ui package in flutter/packagesp: go_routerThe go_router packagepackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework teamworkaround availableThere is a workaround available to overcome the issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions