What package does this bug report belong to?
go_router
What target platforms are you seeing this bug on?
Android, iOS
Have you already upgraded your packages?
Yes
Dependency versions
pubspec.lock
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
characters:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.4.0"
collection:
dependency: transitive
description:
name: collection
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
go_router:
dependency: "direct main"
description:
name: go_router
sha256: eff94d2a6fc79fa8b811dde79c7549808c2346037ee107a1121b4a644c745f2a
url: "https://pub.dev"
source: hosted
version: "17.0.1"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.17.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.2.0"
sdks:
dart: ">=3.9.0 <4.0.0"
flutter: ">=3.35.0"
Steps to reproduce
Using the provided code:
- tap "Go to Details" button ( context.push() )
- tap "Back" button ( context.pop() )
- page is not popped
Things to note:
- both declared routes are at the same level
- navigation is done via
context.push() and context.pop(), not context.go()
Problem:
This problem appears only when both top-level onEnter and top-level redirect callbacks return a Future AND the route you try to pop has an onExit callback (async or sync).
In my example, the bug disappears if you either:
- remove the
onEnter
- make
onEnter synchronous
- remove the
redirect
- make
redirect synchronous
- remove the
onExit callback from the route being pop
Also keep in mind that go_router_builder systematically creates an onExit callback (that returns true) for the generated routes, even when no override is provided, which is different from the behavior of a "manual" GoRoute, because not giving an onExit callback to GoRoute the constructor will lead to onExit being null.
So this problem can pop when migrating to go_router_builder, because it will add a default onExit callbacks to GoRoute that previously had a null onExit.
Expected results
When tapping the "Back" button on the Details page, it should pop the current route and show the Home page
Actual results
When tapping the "Back" button on the Details page, the route is not popped and nothing happens.
If I tap again, an Exception is thrown. (see the stacktrace below)
Code sample
Code sample
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(_) {
return MaterialApp.router(
routerConfig: GoRouter(
debugLogDiagnostics: true,
onEnter: (_, __, ___, ____) => Future.value(const Allow()), // <=======
redirect: (_, __) => Future.value(null), // <=======
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (_, __) => const HomePage(),
),
GoRoute(
path: '/details',
builder: (_, __) => const DetailsPage(),
onExit: (_, __) => Future.value(true), // <=======
),
],
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Home page'),
ElevatedButton(
onPressed: () => context.push('/details'), // <=======
child: const Text('Go to Details'),
),
],
),
),
);
}
}
class DetailsPage extends StatelessWidget {
const DetailsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Details page'),
ElevatedButton(
onPressed: () => context.pop(), // <=======
child: const Text('Back'),
),
],
),
),
);
}
}
Screenshots or Videos
Screenshots / Video demonstration
Not working:
https://github.com/user-attachments/assets/5f0c78e9-4547-4526-b7b2-58ada099c6e8
Working (no onEnter OR no redirect):
https://github.com/user-attachments/assets/9a03915b-30a0-4ae3-aac6-f614765eaaba
Logs
Logs
Launching the app and tapping "Go To Details" button:
[GoRouter] Full paths for routes:
├─/ (HomePage)
└─/details (DetailsPage)
[GoRouter] setting initial location null
[GoRouter] Using MaterialApp configuration
[GoRouter] pushing /details
Pressing "Back" button on Details page (page is not popped):
[GoRouter] popping /
[GoRouter] restoring /
Pressing a second time the "Back" button:
[GoRouter] popping /
[GoRouter] restoring /
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Bad state: Future already completed
#0 _AsyncCompleter.complete (dart:async/future_impl.dart:97:31)
#1 ImperativeRouteMatch.complete (package:go_router/src/match.dart:489:15)
#2 GoRouterDelegate._completeRouteMatch (package:go_router/src/delegate.dart:187:14)
#3 GoRouterDelegate._handlePopPageWithRouteMatch.<anonymous closure> (package:go_router/src/delegate.dart:167:9)
<asynchronous suspension>
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.38.4, on macOS 26.2 25C56 darwin-arm64, locale en-FR) [7.4s]
• Flutter version 3.38.4 on channel stable at /Users/REDACTED/fvm/versions/3.38.4
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 66dd93f9a2 (2 weeks ago), 2025-12-03 14:56:10 -0800
• Engine revision a5cb96369e
• Dart version 3.10.3
• DevTools version 2.51.1
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file, enable-lldb-debugging
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [9.7s]
• Android SDK at /Users/REDACTED/Library/Android/sdk
• Emulator version 36.2.12.0 (build_id 14214601) (CL:N/A)
• Platform android-36, build-tools 36.1.0
• Java binary at: /Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home/bin/java
This JDK is specified in your Flutter configuration.
To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment Homebrew (build 17.0.13+0)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 26.2) [13.3s]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17C52
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [11ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (4 available) [8.6s]
• iPhone 15 Pro (iOS 26.2) (mobile) • 8630355B-90A8-450F-A036-C213C21DC870 • ios • com.apple.CoreSimulator.SimRuntime.iOS-26-2 (simulator)
• iPhone 15 Pro (mobile) • 3D789230-DF92-4EF7-89E6-1E9072D77DEA • ios • com.apple.CoreSimulator.SimRuntime.iOS-26-1 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 26.2 25C56 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 140.0.7339.133
[✓] Network resources [281ms]
• All expected network resources are available.
• No issues found!
What package does this bug report belong to?
go_router
What target platforms are you seeing this bug on?
Android, iOS
Have you already upgraded your packages?
Yes
Dependency versions
pubspec.lock
Steps to reproduce
Using the provided code:
Things to note:
context.push()andcontext.pop(), notcontext.go()Problem:
This problem appears only when both top-level
onEnterand top-levelredirectcallbacks return aFutureAND the route you try to pop has anonExitcallback (async or sync).In my example, the bug disappears if you either:
onEnteronEntersynchronousredirectredirectsynchronousonExitcallback from the route being popAlso keep in mind that
go_router_buildersystematically creates anonExitcallback (that returnstrue) for the generated routes, even when no override is provided, which is different from the behavior of a "manual"GoRoute, because not giving anonExitcallback toGoRoutethe constructor will lead toonExitbeingnull.So this problem can pop when migrating to
go_router_builder, because it will add a defaultonExitcallbacks to GoRoute that previously had a nullonExit.Expected results
When tapping the "Back" button on the Details page, it should pop the current route and show the Home page
Actual results
When tapping the "Back" button on the Details page, the route is not popped and nothing happens.
If I tap again, an Exception is thrown. (see the stacktrace below)
Code sample
Code sample
Screenshots or Videos
Screenshots / Video demonstration
Not working:
https://github.com/user-attachments/assets/5f0c78e9-4547-4526-b7b2-58ada099c6e8
Working (no onEnter OR no redirect):
https://github.com/user-attachments/assets/9a03915b-30a0-4ae3-aac6-f614765eaaba
Logs
Logs
Launching the app and tapping "Go To Details" button:
Pressing "Back" button on Details page (page is not popped):
Pressing a second time the "Back" button:
Flutter Doctor output
Doctor output