Repository navigation
Disposed AppLifecycleListener's onExitRequested is still called if disposed in another AppLifecycleListener #189472
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-linuxBuilding on or for Linux specificallyBuilding on or for Linux specificallyplatform-macosBuilding on or for macOS specificallyBuilding on or for macOS specificallyteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Description
Steps to reproduce
Found on Linux (Fedora 44 KDE). Not sure if it reproduces on other platforms.
flutter create --platforms linux app_lc_test && cd app_lc_test- Copy the reproducer code to
main.dart. flutter runorflutter run --release- Close the app.
- Observe assertion in debug mode or disposed listener getting called in release mode (
AppLifecycleWidget: Exit requestedoutput)
The issue was originally found when TextFields removed from widget tree in onExitRequested caused the assertion be thrown at exit. It was quite confusing at first because I only had one AppLifecycleListener in my code which certainly was not disposed. AppLifecycleWidget() in line 47 can be replaced with TextField() to reproduce that behavior in debug mode.
Expected results
No assertion thrown in debug mode and disposed listener is not called in release mode (no AppLifecycleWidget: Exit requested output).
Actual results
Assertion is thrown in debug mode and disposed listener is called in release mode (AppLifecycleWidget: Exit requested output).
Code sample
Code sample
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final AppLifecycleListener listener;
bool showLcWidget = true;
@override
void initState() {
super.initState();
listener = AppLifecycleListener(
onExitRequested: () async {
print('MyApp: Exit requested');
setState(() {
showLcWidget = false;
});
// Some exit procedure taking its time so that the other
// AppLifecycleListener gets disposed.
await Future.delayed(Duration(milliseconds: 200));
return AppExitResponse.exit;
},
);
}
@override
void dispose() {
listener.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: showLcWidget ? const AppLifecycleWidget() : const SizedBox(),
),
);
}
}
class AppLifecycleWidget extends StatefulWidget {
const AppLifecycleWidget({super.key});
@override
State<AppLifecycleWidget> createState() => _AppLifecycleWidgetState();
}
class _AppLifecycleWidgetState extends State<AppLifecycleWidget> {
late final AppLifecycleListener listener;
@override
void initState() {
super.initState();
listener = AppLifecycleListener(
onExitRequested: () async {
print('AppLifecycleWidget: Exit requested');
return AppExitResponse.exit;
},
);
}
@override
void dispose() {
listener.dispose();
print('AppLifecycleWidget: listener disposed');
super.dispose();
}
@override
Widget build(BuildContext context) => Text('AppLifecycleWidget here');
}
Screenshots or Video
N/A
Logs
`flutter run` output
MyApp: Exit requested
AppLifecycleWidget: listener disposed
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for
WidgetsBindingObserver.didRequestAppExit:
A AppLifecycleListener was used after being disposed.
Once you have called dispose() on a AppLifecycleListener, it can no longer be used.
When the exception was thrown, this was the stack:
#0 AppLifecycleListener._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/widgets/app_lifecycle_listener.dart:192:9)
#1 AppLifecycleListener._debugAssertNotDisposed (package:flutter/src/widgets/app_lifecycle_listener.dart:199:6)
#2 AppLifecycleListener.didRequestAppExit (package:flutter/src/widgets/app_lifecycle_listener.dart:205:12)
#3 WidgetsBinding.handleRequestAppExit (package:flutter/src/widgets/binding.dart:899:29)
<asynchronous suspension>
#4 ServicesBinding._handlePlatformMessage (package:flutter/src/services/binding.dart:441:47)
<asynchronous suspension>
#5 MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:607:42)
<asynchronous suspension>
#6 _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (package:flutter/src/services/binding.dart:663:22)
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════════════════════════
`flutter run --release` output
MyApp: Exit requested
AppLifecycleWidget: listener disposed
AppLifecycleWidget: Exit requestedFlutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.44.6, on Fedora Linux 44 (KDE Plasma Desktop Edition) 7.1.3-200.fc44.x86_64, locale en_US.UTF-8) [88ms]
• Flutter version 3.44.6 on channel stable at /home/user/dev-tools/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision ee80f08bbf (6 days ago), 2026-07-08 15:02:06 -0700
• Engine revision 83675ed276
• Dart version 3.12.2
• DevTools version 2.57.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations,
enable-native-assets, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [2.9s]
• Android SDK at /home/user/dev-tools/android/sdk
• Emulator version 36.6.11.0 (build_id 15507667) (CL:N/A)
• Platform android-36, build-tools 36.1.0
• Java binary at: /home/user/dev-tools/android/android-studio/jbr/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 21.0.6+-13368085-b895.109)
• All Android licenses accepted.
[✓] Chrome - develop for the web [19ms]
• CHROME_EXECUTABLE = /usr/bin/chromium-browser
[✓] Linux toolchain - develop for Linux desktop [408ms]
• clang version 22.1.8 (Fedora 22.1.8-1.fc44)
• cmake version 4.3.0
• ninja version 1.13.2
• pkg-config version 2.5.1
• OpenGL core renderer: AMD Radeon RX 7600 (radeonsi, navi33, ACO, DRM 3.64, 7.1.3-200.fc44.x86_64)
• OpenGL core version: 4.6 (Core Profile) Mesa 26.1.4
• OpenGL core shading language version: 4.60
• OpenGL ES renderer: AMD Radeon RX 7600 (radeonsi, navi33, ACO, DRM 3.64, 7.1.3-200.fc44.x86_64)
• OpenGL ES version: OpenGL ES 3.2 Mesa 26.1.4
• OpenGL ES shading language version: OpenGL ES GLSL ES 3.20
• GL_EXT_framebuffer_blit: yes
• GL_EXT_texture_format_BGRA8888: yes
[✓] Connected device (2 available) [218ms]
• Linux (desktop) • linux • linux-x64 • Fedora Linux 44 (KDE Plasma Desktop Edition) 7.1.3-200.fc44.x86_64
• Chrome (web) • chrome • web-javascript • Chromium 150.0.7871.114 Built from source for Fedora release 44 (Forty Four)
[✓] Network resources [902ms]
• All expected network resources are available.
• No issues found!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-linuxBuilding on or for Linux specificallyBuilding on or for Linux specificallyplatform-macosBuilding on or for macOS specificallyBuilding on or for macOS specificallyteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Activity
suryaKommana2662 commentedon Jul 15, 2026
@hamaaja Thanks for the detailed report and the reproducible sample!
I was able to reproduce this issue on Linux (Debian GNU/Linux 13) using the provided sample.
Observed behavior:
After closing the application, the following output is observed:
This is followed by the assertion:
Environment:
Also verified the behavior on macOS:
In debug mode (
flutter run -d macos), the same assertion is thrown afterMyApp: Exit requestedandAppLifecycleWidget: listener disposed.In release mode (
flutter run -d macos --release), the disposedAppLifecycleListenerstill receives theonExitRequestedcallback (AppLifecycleWidget: Exit requested), matching the behavior reported on Linux.The behavior matches the reported issue. The disposed
AppLifecycleListenerstill receives theonExitRequestedcallback during application exit. Routing this toteam-frameworkfor further investigation.Skip removed observers during app exit requests (flutter#190343)
github-actions commentedon Sep 8, 2026
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 -vand a minimal reproduction of the issue.