Explain asynchronous causes in the setState() called after dispose() error#187294
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the setState() error message in framework.dart to explain that the error can occur after asynchronous operations complete when the widget is no longer in the tree, and highlights checking the mounted property after an await. It also adds a test in framework_test.dart to verify this error message. Feedback suggests simplifying the phrasing of the error message to improve readability.
| 'setState() from a timer, from an animation callback, or after an ' | ||
| 'asynchronous operation (such as an awaited network request or other ' | ||
| 'Future) completes once the widget has already been removed from the tree.', |
There was a problem hiding this comment.
The phrase "completes once the widget has already been removed" is slightly wordy and ambiguous. Simplifying this to "completes after the widget has been removed" makes the error message more direct and easier to read, which aligns with the Flutter philosophy of optimizing for readability and making error messages highly useful.
'setState() from a timer, from an animation callback, or after an '\n 'asynchronous operation (such as an awaited network request or other '\n 'Future) completes after the widget has been removed from the tree.',References
- Optimize for readability: Code is read more often than it is written. Error messages should be useful: Every error message is an opportunity to make someone love our product. (link)
There was a problem hiding this comment.
Done in 18f5595 — simplified to "...completes after the widget has been removed from the tree."
| 'tree; this is especially important after an "await", since the widget ' | ||
| 'may have been removed from the tree while the asynchronous work was in ' | ||
| 'progress.', |
There was a problem hiding this comment.
Nitpick here: I think it's not "especially" true after an await. That case is on equal footing with all of the others that are mentioned. IMO this addition here is not necessary, and the information here is already covered in the ErorrDescription.
Are you worried that readers might not get the point that they should check mounted after await?
There was a problem hiding this comment.
You're right — await isn't special here, it's on equal footing with the timer and animation-callback cases, and the asynchronous cause is already spelled out in the ErrorDescription above. My intent was just to nudge people toward the mounted-after-await check, but since the description already covers it, the extra emphasis in the hint is redundant. I've dropped that addition (fb7904d) so the hint stays consistent across all the causes. Thanks for the catch!
…error The setState() called after dispose() error listed only timers and animation callbacks as triggers. The most common real-world cause is an asynchronous gap: an awaited Future completes after the widget was removed from the tree (for example, after the route was popped). Extend the ErrorDescription and ErrorHint to name that cause and point at the mounted-after-await fix (the pattern the use_build_context_synchronously lint enforces). No behavior change. Fixes flutter#177615
Use 'completes after the widget has been removed from the tree' instead of 'completes once the widget has already been removed from the tree' for a more direct error message, per review feedback.
ac99ee7 to
6ceb2ab
Compare
…error (flutter#187294) ## Description The `setState() called after dispose()` assertion currently lists only *a timer or an animation callback* as the situations that trigger it. In real apps the most common cause is an **asynchronous gap**: code `await`s a `Future` (a network request, `Future.delayed`, etc.), the widget is removed from the tree while the work is in flight (for example, the route is popped), and the continuation then calls `setState()` on the now-defunct `State`. This PR extends the existing `ErrorDescription` and the first `ErrorHint` to: - name the asynchronous-gap cause alongside timers / animation callbacks, and - point at the canonical fix — guarding `setState()` with a `mounted` check after an `await` (the pattern enforced by the `use_build_context_synchronously` lint). No behavior changes — this only makes the diagnostic more actionable, especially for beginners (the concern raised in the issue). **Before** > … This error can occur when code calls setState() from a timer or an animation callback. **After** > … This error can occur when code calls setState() from a timer, from an animation callback, or after an asynchronous operation (such as an awaited network request or other Future) completes once the widget has already been removed from the tree. …and the first hint now adds that checking `mounted` is *"especially important after an `await`."* I deliberately did **not** embed a documentation URL in the message (suggested in the issue), since the framework error messages avoid inline links and the existing `mounted` guidance already states the remedy. ## Related Issues Fixes flutter#177615 ## Tests Added `packages/flutter/test/widgets/framework_test.dart` → **`setState() after dispose() error explains asynchronous causes`**, which asserts the thrown `FlutterError` message mentions the asynchronous cause and the `await` / `mounted` guidance. The existing `Defunct setState throws exception` test continues to pass; `flutter analyze` reports no issues and `dart format` reports no changes. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [CLA]: https://cla.developers.google.com/
…12137) Manual roll Flutter from 6995038d96ef to 91939cc4db78 (48 revisions) Manual roll requested by [email protected] flutter/flutter@6995038...91939cc 2026-07-07 [email protected] Roll Skia from 80ae1deed9ed to 075fbe4778d9 (6 revisions) (flutter/flutter#189067) 2026-07-07 [email protected] Bump customer testing version for new registrants (flutter/flutter#189070) 2026-07-07 [email protected] Roll Packages from fc00ceb to 92525f5 (2 revisions) (flutter/flutter#189069) 2026-07-07 [email protected] fix android semantics integration test hangs due to postframe callback (flutter/flutter#189043) 2026-07-07 [email protected] Bump goldctl (flutter/flutter#189030) 2026-07-07 [email protected] Roll Skia from 71db7c06c5fe to 80ae1deed9ed (2 revisions) (flutter/flutter#189060) 2026-07-07 [email protected] Collect analytics on AI agent usage (flutter/flutter#187630) 2026-07-07 [email protected] Roll Skia from 125a76cc4cf3 to 71db7c06c5fe (4 revisions) (flutter/flutter#189054) 2026-07-07 [email protected] Roll Dart SDK from 70577d6f2bba to c648e3429d76 (1 revision) (flutter/flutter#189052) 2026-07-07 [email protected] Fix RenderSliverPadding setter assertion (flutter/flutter#187353) 2026-07-07 [email protected] Roll Skia from 2dde156aec3e to 125a76cc4cf3 (3 revisions) (flutter/flutter#189037) 2026-07-07 [email protected] Explain asynchronous causes in the setState() called after dispose() error (flutter/flutter#187294) 2026-07-07 [email protected] Roll Skia from 7dccd1e79a5b to 2dde156aec3e (2 revisions) (flutter/flutter#189035) 2026-07-07 [email protected] Add `STRING_CATALOG_GENERATE_SYMBOLS = YES;` (flutter/flutter#188163) 2026-07-07 [email protected] Print warnings on Intel Macs / targeting Intel Macs (flutter/flutter#188835) 2026-07-07 [email protected] Roll Dart SDK from 4c03f64b19f6 to 70577d6f2bba (1 revision) (flutter/flutter#189031) 2026-07-07 [email protected] Roll Fuchsia Linux SDK from n1Lm2Z4DZkfC3bwj5... to 7RjQJBW3m-3Jl-7jr... (flutter/flutter#189032) 2026-07-06 [email protected] Recommend `OverlayPortal.overlayChildLayoutBuilder` over Target-Follower (flutter/flutter#188894) 2026-07-06 [email protected] Sync CHANGELOG.md from stable (flutter/flutter#189025) 2026-07-06 [email protected] Rename preferredSize to size and preferredConstraints to constraints in the windowing API (flutter/flutter#189017) 2026-07-06 [email protected] Skip locked issues in no-response check (flutter/flutter#188950) 2026-07-06 [email protected] Fix potential race condtion in android_semantics_integration_test (flutter/flutter#188830) 2026-07-06 [email protected] ci: udpate wait-for-engine-build composite action to cocoon (flutter/flutter#189020) 2026-07-06 [email protected] Roll Skia from 2b55eed5500d to 7dccd1e79a5b (3 revisions) (flutter/flutter#189021) 2026-07-06 [email protected] [AGP 9] Update Flutter Template Versions (flutter/flutter#188762) 2026-07-06 [email protected] fix(engine/windows): keep tooltip position rect alive - fix use after free (flutter/flutter#188476) 2026-07-06 [email protected] [Tool] Fix null check operator crash in currentPackageConfig (flutter/flutter#188454) 2026-07-06 [email protected] [Tool] Gracefully handle WDAC/AppLocker blocks for impellerc (flutter/flutter#188452) 2026-07-06 [email protected] [flutter_tools] Throw DaemonException if app fails to start early (flutter/flutter#188921) 2026-07-06 [email protected] Roll Dart SDK from ce7a2567eb59 to 4c03f64b19f6 (2 revisions) (flutter/flutter#189015) 2026-07-06 [email protected] [flutter_tools, engine] Add --disable-service-origin-check option to disable VM service origin checks (flutter/flutter#188745) 2026-07-06 [email protected] [flutter_tools] Fix test flakiness in widget_preview_detection_test.dart (flutter/flutter#188922) 2026-07-06 [email protected] Roll pub packages (flutter/flutter#189009) 2026-07-06 [email protected] Roll Skia from c0e2b9667d91 to 2b55eed5500d (1 revision) (flutter/flutter#189006) 2026-07-06 [email protected] Roll Packages from 2fbe873 to fc00ceb (1 revision) (flutter/flutter#189007) 2026-07-06 [email protected] Roll Skia from b68567542f81 to c0e2b9667d91 (1 revision) (flutter/flutter#189004) 2026-07-06 [email protected] Fixing multiline GetBoxesForRange (flutter/flutter#188803) 2026-07-06 [email protected] Roll Skia from e15ea7a4b927 to b68567542f81 (4 revisions) (flutter/flutter#189000) 2026-07-06 [email protected] Roll Skia from 79806692425f to e15ea7a4b927 (2 revisions) (flutter/flutter#188992) 2026-07-06 [email protected] Roll Skia from 2826ae6dc649 to 79806692425f (1 revision) (flutter/flutter#188991) 2026-07-06 [email protected] Roll Skia from 7f99eee20fd6 to 2826ae6dc649 (1 revision) (flutter/flutter#188990) 2026-07-06 [email protected] Add debugPaintFocusBoxes (flutter/flutter#188288) 2026-07-05 [email protected] Roll Fuchsia Linux SDK from bkK6BLiZDRnE7AQQj... to n1Lm2Z4DZkfC3bwj5... (flutter/flutter#188989) 2026-07-05 [email protected] Roll Skia from 75a4bf6706bd to 7f99eee20fd6 (2 revisions) (flutter/flutter#188988) ...
…lutter#12137) Manual roll Flutter from 6995038d96ef to 91939cc4db78 (48 revisions) Manual roll requested by [email protected] flutter/flutter@6995038...91939cc 2026-07-07 [email protected] Roll Skia from 80ae1deed9ed to 075fbe4778d9 (6 revisions) (flutter/flutter#189067) 2026-07-07 [email protected] Bump customer testing version for new registrants (flutter/flutter#189070) 2026-07-07 [email protected] Roll Packages from fc00ceb to 92525f5 (2 revisions) (flutter/flutter#189069) 2026-07-07 [email protected] fix android semantics integration test hangs due to postframe callback (flutter/flutter#189043) 2026-07-07 [email protected] Bump goldctl (flutter/flutter#189030) 2026-07-07 [email protected] Roll Skia from 71db7c06c5fe to 80ae1deed9ed (2 revisions) (flutter/flutter#189060) 2026-07-07 [email protected] Collect analytics on AI agent usage (flutter/flutter#187630) 2026-07-07 [email protected] Roll Skia from 125a76cc4cf3 to 71db7c06c5fe (4 revisions) (flutter/flutter#189054) 2026-07-07 [email protected] Roll Dart SDK from 70577d6f2bba to c648e3429d76 (1 revision) (flutter/flutter#189052) 2026-07-07 [email protected] Fix RenderSliverPadding setter assertion (flutter/flutter#187353) 2026-07-07 [email protected] Roll Skia from 2dde156aec3e to 125a76cc4cf3 (3 revisions) (flutter/flutter#189037) 2026-07-07 [email protected] Explain asynchronous causes in the setState() called after dispose() error (flutter/flutter#187294) 2026-07-07 [email protected] Roll Skia from 7dccd1e79a5b to 2dde156aec3e (2 revisions) (flutter/flutter#189035) 2026-07-07 [email protected] Add `STRING_CATALOG_GENERATE_SYMBOLS = YES;` (flutter/flutter#188163) 2026-07-07 [email protected] Print warnings on Intel Macs / targeting Intel Macs (flutter/flutter#188835) 2026-07-07 [email protected] Roll Dart SDK from 4c03f64b19f6 to 70577d6f2bba (1 revision) (flutter/flutter#189031) 2026-07-07 [email protected] Roll Fuchsia Linux SDK from n1Lm2Z4DZkfC3bwj5... to 7RjQJBW3m-3Jl-7jr... (flutter/flutter#189032) 2026-07-06 [email protected] Recommend `OverlayPortal.overlayChildLayoutBuilder` over Target-Follower (flutter/flutter#188894) 2026-07-06 [email protected] Sync CHANGELOG.md from stable (flutter/flutter#189025) 2026-07-06 [email protected] Rename preferredSize to size and preferredConstraints to constraints in the windowing API (flutter/flutter#189017) 2026-07-06 [email protected] Skip locked issues in no-response check (flutter/flutter#188950) 2026-07-06 [email protected] Fix potential race condtion in android_semantics_integration_test (flutter/flutter#188830) 2026-07-06 [email protected] ci: udpate wait-for-engine-build composite action to cocoon (flutter/flutter#189020) 2026-07-06 [email protected] Roll Skia from 2b55eed5500d to 7dccd1e79a5b (3 revisions) (flutter/flutter#189021) 2026-07-06 [email protected] [AGP 9] Update Flutter Template Versions (flutter/flutter#188762) 2026-07-06 [email protected] fix(engine/windows): keep tooltip position rect alive - fix use after free (flutter/flutter#188476) 2026-07-06 [email protected] [Tool] Fix null check operator crash in currentPackageConfig (flutter/flutter#188454) 2026-07-06 [email protected] [Tool] Gracefully handle WDAC/AppLocker blocks for impellerc (flutter/flutter#188452) 2026-07-06 [email protected] [flutter_tools] Throw DaemonException if app fails to start early (flutter/flutter#188921) 2026-07-06 [email protected] Roll Dart SDK from ce7a2567eb59 to 4c03f64b19f6 (2 revisions) (flutter/flutter#189015) 2026-07-06 [email protected] [flutter_tools, engine] Add --disable-service-origin-check option to disable VM service origin checks (flutter/flutter#188745) 2026-07-06 [email protected] [flutter_tools] Fix test flakiness in widget_preview_detection_test.dart (flutter/flutter#188922) 2026-07-06 [email protected] Roll pub packages (flutter/flutter#189009) 2026-07-06 [email protected] Roll Skia from c0e2b9667d91 to 2b55eed5500d (1 revision) (flutter/flutter#189006) 2026-07-06 [email protected] Roll Packages from 2fbe873 to fc00ceb (1 revision) (flutter/flutter#189007) 2026-07-06 [email protected] Roll Skia from b68567542f81 to c0e2b9667d91 (1 revision) (flutter/flutter#189004) 2026-07-06 [email protected] Fixing multiline GetBoxesForRange (flutter/flutter#188803) 2026-07-06 [email protected] Roll Skia from e15ea7a4b927 to b68567542f81 (4 revisions) (flutter/flutter#189000) 2026-07-06 [email protected] Roll Skia from 79806692425f to e15ea7a4b927 (2 revisions) (flutter/flutter#188992) 2026-07-06 [email protected] Roll Skia from 2826ae6dc649 to 79806692425f (1 revision) (flutter/flutter#188991) 2026-07-06 [email protected] Roll Skia from 7f99eee20fd6 to 2826ae6dc649 (1 revision) (flutter/flutter#188990) 2026-07-06 [email protected] Add debugPaintFocusBoxes (flutter/flutter#188288) 2026-07-05 [email protected] Roll Fuchsia Linux SDK from bkK6BLiZDRnE7AQQj... to n1Lm2Z4DZkfC3bwj5... (flutter/flutter#188989) 2026-07-05 [email protected] Roll Skia from 75a4bf6706bd to 7f99eee20fd6 (2 revisions) (flutter/flutter#188988) ...
Description
The
setState() called after dispose()assertion currently lists only a timer or an animation callback as the situations that trigger it. In real apps the most common cause is an asynchronous gap: codeawaits aFuture(a network request,Future.delayed, etc.), the widget is removed from the tree while the work is in flight (for example, the route is popped), and the continuation then callssetState()on the now-defunctState.This PR extends the existing
ErrorDescriptionand the firstErrorHintto:setState()with amountedcheck after anawait(the pattern enforced by theuse_build_context_synchronouslylint).No behavior changes — this only makes the diagnostic more actionable, especially for beginners (the concern raised in the issue).
Before
After
…and the first hint now adds that checking
mountedis "especially important after anawait."I deliberately did not embed a documentation URL in the message (suggested in the issue), since the framework error messages avoid inline links and the existing
mountedguidance already states the remedy.Related Issues
Fixes #177615
Tests
Added
packages/flutter/test/widgets/framework_test.dart→setState() after dispose() error explains asynchronous causes, which asserts the thrownFlutterErrormessage mentions the asynchronous cause and theawait/mountedguidance. The existingDefunct setState throws exceptiontest continues to pass;flutter analyzereports no issues anddart formatreports no changes.Pre-launch Checklist