flutter / flutter/flutter

'Bad state: Future already completed' navigation error on push() right after await push() return

Open
#139,144 1 comment 3 reactions 0 assignees View on GitHub
c: crash found in release: 3.16 found in release: 3.17 has reproducible steps p: go_router P2 package team-ecosystem triaged-ecosystem
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Is there an existing issue for this?

- [X] I have searched the [existing package issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Apackage)
- [X] I have read the [guide to filing a bug](https://flutter.dev/docs/resources/bug-reports)

### 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

```lock
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_test:
dependency: "direct dev"
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: c247a4f76071c3b97bb5ae8912968870d5565644801c5e09f3bc961b4d874895
url: "https://pub.dev"
source: hosted
version: "12.1.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.10.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
sdks:
dart: ">=3.2.1 <4.0.0"
flutter: ">=3.7.0"

```

### Steps to reproduce

1. Run provided example code
2. On the intitial screen press '+' fab button

What the app does is that it pushes PageTwo on a fab press and then after 100 ms that page performs pop() operation
After the aforementioned push() returns from await another page (PageThree) is pushed.

It sometimes (very rarely) works properly.
More often than not it crashes.

### Expected results

Route '/three' is visible with '/' page below it

### Actual results

Complete crash of navigation framework with error screen in debug mode and empty screen in profile mode

### Code sample

Code sample

```dart
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});

static final goRouter = GoRouter(
debugLogDiagnostics: true,
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return const MyHomePage(title: 'Press the fab');
},
),
GoRoute(
path: '/two',
builder: (context, state) {
return const PageTwo();
},
),
GoRoute(
path: '/three',
builder: (context, state) {
return const PageThree();
},
),
],
);

@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: goRouter,
title: 'Bug Demo',
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
required this.title,
});

final String title;

@override
State createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter();
_goToPage2Then3(context);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}

Future _goToPage2Then3(BuildContext context) async {
final goRouter = GoRouter.of(context);
await goRouter.push('/two');
goRouter.push('/three');
}
}

class PageTwo extends StatefulWidget {
const PageTwo({
super.key,
});

@override
State createState() => _PageTwoState();
}

class _PageTwoState extends State {
@override
void didChangeDependencies() {
super.didChangeDependencies();
final goRouter = GoRouter.of(context);
Future.delayed(
const Duration(milliseconds: 100),
goRouter.pop,
);

// Regular pop gives the same error
// final navigator = Navigator.of(context);
// Future.delayed(
// const Duration(milliseconds: 100),
// navigator.pop,
// );
}

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

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

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Page 3'),
),
),
);
}
}

```

### Screenshots or Videos

Screenshots / Video demonstration

[Upload media here]

### Logs

Logs

```console
I/ViewRootImpl@8ed4562[MainActivity](22255): ViewPostIme pointer 0
I/ViewRootImpl@8ed4562[MainActivity](22255): ViewPostIme pointer 1
I/ViewRootImpl@8ed4562[MainActivity](22255): ViewPostIme pointer 0
I/ViewRootImpl@8ed4562[MainActivity](22255): ViewPostIme pointer 1
[GoRouter] pushing /two
W/OnBackInvokedCallback(22255): OnBackInvokedCallback is not enabled for the application.
W/OnBackInvokedCallback(22255): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
[GoRouter] pushing /three
I/flutter (22255): Bad state: Future already completed
I/flutter (22255): #1 Route.didComplete (package:flutter/src/widgets/navigator.dart:418)
I/flutter (22255): #2 _RouteEntry.handleComplete (package:flutter/src/widgets/navigator.dart:3052)
I/flutter (22255): #3 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:4257)
I/flutter (22255): #4 NavigatorState._updatePages (package:flutter/src/widgets/navigator.dart:4161)
I/flutter (22255): #5 NavigatorState.didUpdateWidget (package:flutter/src/widgets/navigator.dart:3803)
I/flutter (22255): #6 StatefulElement.update (package:flutter/src/widgets/framework.dart:5643)
I/flutter (22255): #7 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #8 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #9 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #10 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800)
I/flutter (22255): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #14 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800)
I/flutter (22255): #15 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:105)
I/flutter (22255): #16 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #17 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #18 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #19 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547)
I/flutter (22255): #20 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #21 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #22 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #23 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800)
I/flutter (22255): #24 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #25 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #26 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #27 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547)
I/flutter (22255): #28 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #29 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #30 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #31 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800)
I/flutter (22255): #32 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #33 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #34 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #35 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800)
I/flutter (22255): #36 Element.updateChild (package:flutter/src/widgets/framework.dart:3815)
I/flutter (22255): #37 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496)
I/flutter (22255): #38 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634)
I/flutter (22255): #39 Element.rebuild (package:flutter/src/widgets/framework.dart:5187)
I/flutter (22255): #40 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2895)
I/flutter (22255): #41 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:984)
I/flutter (22255): #42 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457)
I/flutter (22255): #43 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325)
I/flutter (22255): #44 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255)
I/flutter (22255): #45 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113)
I/flutter (22255): #46 _invoke (dart:ui/hooks.dart:312)
I/flutter (22255): #47 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383)
I/flutter (22255): #48 _drawFrame (dart:ui/hooks.dart:283)
I/flutter (22255): (elided one frame from dart:async)
W/OnBackInvokedCallback(22255): OnBackInvokedCallback is not enabled for the application.
W/OnBackInvokedCallback(22255): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
E/flutter (22255): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Future already completed
E/flutter (22255): #0 _AsyncCompleter.complete (dart:async/future_impl.dart:43)
E/flutter (22255): #1 Route.didComplete (package:flutter/src/widgets/navigator.dart:418)
E/flutter (22255): #2 _RouteEntry.handleComplete (package:flutter/src/widgets/navigator.dart:3052)
E/flutter (22255): #3 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:4257)
E/flutter (22255): #4 _RouteEntry.handlePush. (package:flutter/src/widgets/navigator.dart:2995)
E/flutter (22255): #5 TickerFuture.whenCompleteOrCancel.thunk (package:flutter/src/scheduler/ticker.dart:420)
E/flutter (22255): #6 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:846)
E/flutter (22255): #7 Future._propagateToListeners (dart:async/future_impl.dart:875)
E/flutter (22255): #8 Future._completeWithValue (dart:async/future_impl.dart:647)
E/flutter (22255): #9 Future._asyncCompleteWithValue. (dart:async/future_impl.dart:721)
E/flutter (22255): #10 _microtaskLoop (dart:async/schedule_microtask.dart:40)
E/flutter (22255): #11 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49)
E/flutter (22255):

```

### Flutter Doctor output

Doctor output

```console
[✓] Flutter (Channel stable, 3.16.1, on macOS 13.6 22G120 darwin-arm64, locale pl-PL)
• Flutter version 3.16.1 on channel stable at /***/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7f20e5d18c (21 hours ago), 2023-11-27 09:47:30 -0800
• Engine revision 22b600f240
• Dart version 3.2.1
• DevTools version 2.28.3

[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /***/Android/sdk
• Platform android-34, build-tools 34.0.0
✗ Android SDK file not found: /***/Android/sdk/platforms/android-34/android.jar.
• Try re-installing or updating your Android SDK,
visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions.

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14C18
• CocoaPods version 1.12.1

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

[✓] Android Studio (version 2022.2)
• 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.6b802.4-9586694)

[✓] Proxy Configuration
***

[✓] Connected device (3 available)
• SM M236B (mobile) • *** • android-arm64 • Android 13 (API 33)
• macOS (desktop) • macos • darwin-arm64 • macOS 13.6 22G120 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 119.0.6045.159

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

! Doctor found issues in 1 category.

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.