Short answer
Find the .of(context) call on the first stack trace line in your own code. If it runs after an await, add if (!context.mounted) return; right before it (or if (!mounted) return; inside a State). If it runs in dispose(), look the object up in didChangeDependencies, keep it in a field, and use the field in dispose. If it runs after Navigator.pop, use the navigator or messenger you looked up before the pop. The analyzer lint use_build_context_synchronously flags the after-await case.
Where the stale context comes from, and the fix
01
A context used after an await
“If a BuildContext is used across an asynchronous gap (i.e. after performing an asynchronous operation), consider checking mounted to determine whether the context is still valid before interacting with it” Flutter, BuildContext class
The user leaves the screen while a network call or a dialog is running. When the await returns, Navigator.of(context) or ScaffoldMessenger.of(context) runs on a widget that is gone. Check mounted after every await that is followed by a context call.
onPressed: () async { await saveProfile(); if (!context.mounted) return; Navigator.of(context).pop(); },02
An .of(context) call in dispose()
“To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.” Flutter, Flutter framework source (the error’s hint)
By the time dispose() runs, the widget is out of the tree, so ScaffoldMessenger.of(context), Provider.of(context) and similar lookups fail there. Look the object up in didChangeDependencies, keep it in a field, and use the field in dispose. .of(context) calls dependOnInheritedWidgetOfExactType() for you, which is why the error’s own hint names it.
late ScaffoldMessengerState _messenger; @override void didChangeDependencies() { super.didChangeDependencies(); _messenger = ScaffoldMessenger.of(context); } @override void dispose() { _messenger.hideCurrentSnackBar(); super.dispose(); }03
A context kept in a field or passed to a service
“Avoid storing instances of BuildContexts because they may become invalid if the widget they are associated with is unmounted from the widget tree.” Flutter, BuildContext class
A BuildContext stored in a variable, a singleton or a long-lived callback outlives its widget. When the code uses it later, the widget may be gone. Pass the context in at the moment it is needed, or use a navigatorKey or scaffoldMessengerKey for app-wide navigation and snackbars.
04
A timer, stream or listener that outlives the screen
“After the framework calls dispose, the State object is considered unmounted and the mounted property is false. It is an error to call setState at this point.” Flutter, State.dispose
A Timer, StreamSubscription or listener keeps firing after the screen closes and calls setState or an .of(context) lookup. Cancel it in dispose, and check mounted at the top of the callback.
Checked against the vendor’s docs on : Flutter API: BuildContext class; Flutter API: State.dispose; Flutter source: framework.dart (the error message and its hint).
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Flutter “setState() called during build” · Flutter LateInitializationError · Flutter “Null check operator used on a null value” · Flutter “type 'Null' is not a subtype of type 'String'”