Skip to content

Add @awaitNotRequired annotation to flutter sdk#181513

Draft
victorsanni wants to merge 12 commits intoflutter:masterfrom
victorsanni:unawaited-futures-draft
Draft

Add @awaitNotRequired annotation to flutter sdk#181513
victorsanni wants to merge 12 commits intoflutter:masterfrom
victorsanni:unawaited-futures-draft

Conversation

@victorsanni
Copy link
Contributor

@victorsanni victorsanni commented Jan 26, 2026

Draft to fix Use @awaitNotRequired in Flutter SDK

Turned on the unawaited_futures lint and added the annotation to every function declared in the flutter SDK and flagged by the linter. This means the annotation is only added to Future-returning functions called at least once without the await keyword preceding it. So if there exists a Future-returning function in the Flutter SDK that does not need to be awaited, but all call sites in the SDK have the await keyword, it is not annotated.

EDIT: Opened PRs to add awaits or ignores to callsites instead of adding the annotation. Some functions may still require this annotation, but this set is much smaller than originally anticipated.

Missing annotation:
integrationDriver :


Because this will require incurring a dependency on package:meta/meta.dart in package:integration_test/integration_test_driver.dart.

@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. labels Jan 26, 2026
@github-actions github-actions bot added a: animation Animation APIs f: material design flutter/packages/flutter/material repository. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) f: scrolling Viewports, list views, slivers, etc. f: cupertino flutter/packages/flutter/cupertino repository f: routes Navigator, Router, and related APIs. f: integration_test The flutter/packages/integration_test plugin labels Jan 26, 2026
@github-actions github-actions bot removed the f: integration_test The flutter/packages/integration_test plugin label Jan 26, 2026
@dkwingsmt
Copy link
Contributor

Do we have a plan on the criteria that justify a @awaitNotRequired? It feels like marking parameters optional, and it might be better off reviewed on a case-by-case basis, even better split into separate PRs based on categories of reasons.

@victorsanni
Copy link
Contributor Author

Do we have a plan on the criteria that justify a @awaitNotRequired?

There is a lint (unawaited_futures) turned off in the Flutter SDK which basically flags Future-returning function call sites without the await keyword. Is there a scenario where a method flagged by this lint should not have the @awaitNotRequired annotation?

}

@awaitNotRequired
Future<void> _rebuild([void value]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the returned future of this private method is never used. Why can't it simply return void?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, i think it was initially added as a Future<void> to satisfy the .then API, but no longer needed to after #100657.

/// Returns a [Future] which completes to the received response, which may
/// be null.
@awaitNotRequired
Future<T?> send(T message) async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we really mark send and invokeMethod as awaitNotRequired? IMO these foundational methods should require await and let individual usages suppress the warning explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, there are other callsites in the framework with await. Should we suppress the warning with an ignore or add awaits?

Copy link
Contributor

@dkwingsmt dkwingsmt Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect many such usages are intentional, probably because those send do not wait for responses. For such cases it's ok to explicitly ignore while commenting that it's intentional to not wait for response. LMK if there are other cases that you're unsure of.

/// The method by which [golden] is located and by which its bytes are written
/// is left up to the implementation class.
@awaitNotRequired
Future<void> update(Uri golden, Uint8List imageBytes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should enforce await. Can you check where it is used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, most of its callsites use await, its non-await callsites are primarily from this test file in this PR: #160484.

I can go ahead and add await to these callsites.

@victorsanni
Copy link
Contributor Author

Thanks for the review @dkwingsmt. I didn't think there are situations in the framework where some Future-returning methods do not have a preceding await but should. This is a valid point and makes sense to me.

Is this review exhaustive? i.e are the methods you've pointed out the only ones that should have await added instead of the annotation? Asking because I want to go ahead and open PRs to add await to the ones you have pointed out.

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Feb 10, 2026

I didn't review the ones under dev since I'm not as familiar. I went through the other files, although I'm not as confident on some cases such as Navigator. In general my recommendation is that this tag should be used with caution since it's basically ignore-lint that applies to all users.

@victorsanni victorsanni marked this pull request as ready for review February 13, 2026 03:34
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the @awaitNotRequired annotation across the Flutter SDK to address unawaited_futures lint warnings. The changes are extensive, touching many files to annotate methods that return a Future but are not intended to be awaited, such as animation controllers, navigation methods, and platform channel invocations. This makes the code cleaner and the intent clearer. Additionally, the PR fixes a few instances in tests where tester.pump() was not correctly awaited. The changes are well-executed and improve the overall code quality by adhering to linting best practices.

@victorsanni victorsanni marked this pull request as draft February 13, 2026 22:57
@dkwingsmt
Copy link
Contributor

dkwingsmt commented Feb 20, 2026

Related: #182233
In this issue, an error slipped through all try-catch efforts and caused app crash. This was caused by the following structure:

void A() {
  assert(false); // Exception thrown
}

Future<void> animateTo() async {
  A();
}

void handleEvent() { // Sync handler
  animateTo();  // The future is not awaited.
}

void D() {
  try {
    handleEvent(); // D thought this was enough catching.
  } catch {
    FlutterError.report(...);
  }
}

This shows the risk of allowing futures to not be awaited: Async errors will not be caught at all.

Therefore I think we should not allow futures to be un-awaited (except maybe in tests, with discretion). All futures should either be awaited or have a .catch.

}

@awaitNotRequired
Future<void> start() async {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dkwingsmt, I see you added this method (and its other clones below) in #59803, did you intend to use it in the postFrameCallback without await?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think awaitNotRequired is ok here, since this is only used in a fully managed test that I expect no errors to occur, and I'm ok with errors being thrown.

_canceled = true;
}

@awaitNotRequired
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the annotation here. This PR added it: #79163? WDYT @dkwingsmt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think having no await is the intention here.

github-merge-queue bot pushed a commit that referenced this pull request Mar 3, 2026
Impl:

```dart
  /// Sends the specified [message] to the platform plugins on this channel.
  ///
  /// Returns a [Future] which completes to the received response, which may
  /// be null.
  Future<T?> send(T message) async {
    return codec.decodeMessage(await binaryMessenger.send(name, codec.encodeMessage(message)));
  }
```

Part of #181513
github-merge-queue bot pushed a commit that referenced this pull request Mar 5, 2026
github-merge-queue bot pushed a commit that referenced this pull request Mar 9, 2026
Part of [Add @awaitNotRequired annotation to flutter
sdk](#181513)
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
Impl:

```dart
  /// Sends the specified [message] to the platform plugins on this channel.
  ///
  /// Returns a [Future] which completes to the received response, which may
  /// be null.
  Future<T?> send(T message) async {
    return codec.decodeMessage(await binaryMessenger.send(name, codec.encodeMessage(message)));
  }
```

Part of flutter#181513
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
@victorsanni victorsanni requested a review from dkwingsmt March 11, 2026 17:55
github-merge-queue bot pushed a commit that referenced this pull request Mar 11, 2026
Part of [Add @awaitNotRequired annotation to flutter
sdk](#181513)
/// which switches to [AnimationStatus.completed] when [upperBound] is
/// reached at the end of the animation.
@awaitNotRequired
TickerFuture forward({double? from}) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment to TickerFuture impl:

A TickerFuture should probably NOT be awaited at all, since it is risky to hang forever. Instead, people who wish to know when/whether it completes will explicitly attach a callback anyway. This should make it reasonable to make mark all TickerFuture as awaitNotRequired.

github-merge-queue bot pushed a commit that referenced this pull request Mar 13, 2026
Part of [Add @awaitNotRequired annotation to flutter
sdk](#181513)
github-merge-queue bot pushed a commit that referenced this pull request Mar 13, 2026
Part of [Add @awaitNotRequired annotation to flutter
sdk](#181513)
@victorsanni victorsanni added the CICD Run CI/CD label Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) a: animation Animation APIs a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems CICD Run CI/CD f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. f: routes Navigator, Router, and related APIs. f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use @awaitNotRequired in Flutter SDK

2 participants