require-atomic-async-updates
Warns when an assignment can lead to a race condition due to await.
An assignment is reported when the rule detects the following execution flow in an async function:
- The variable is read.
- An
awaitpauses the function. - After the function is resumed, a value is assigned to the variable from step 1.
The assignment in step 3 is reported because it may be incorrectly resolved because the value of the variable from step 1 may have changed between steps 2 and 3. In particular, if the variable can be accessed from other execution contexts (for example, if it is not a local variable and therefore other functions can change it), the value of the variable may have changed elsewhere while the function was paused in step 2.
Example
❌ Bad:
int foo = 0;
Future<void> fn(Future<int> amount) async {
// LINT: This reassignment might use an outdated value due to a race condition.
// Consider moving the await expression to its own local variable.
foo += await amount;
// LINT: This reassignment might use an outdated value due to a race condition.
// Consider moving the await expression to its own local variable.
foo = foo + await amount;
}
void main() {
Future.wait([fn(...), fn(...)]); // "fn" is called more than once
}
✅ Good:
int foo = 0;
Future<void> fn(Future<int> amount) async {
final local = await amount;
foo += local;
}