Skip to content

use_setstate_synchronously

v1.0.0WarningConfigurableAsync Safety

This rule flags setState called after an await with no mounted guard in between.

This is a real crash, not a style preference. Between the await and the line after it the widget can be disposed — the user navigated back, a parent rebuilt without this child, a list item scrolled out of a ListView. Calling setState on a disposed State throws setState() called after dispose(), and it does so only under the timing that makes it hard to reproduce and easy to ship.

This is the State counterpart to use_ref_read_synchronously, and it shares that rule’s async-gap machinery. It applies inside any State subclass, including additional bases named through state_base_classes.

This rule is in the recommended preset.

Future<void> load() async {
final data = await repository.fetch();
setState(() => _data = data); // the widget may be gone
}
Future<void> load() async {
final data = await repository.fetch();
if (!mounted) return;
setState(() => _data = data);
}

This rule is on with preset: recommended or preset: opinionated.

analysis_options.yaml
many_lints:
rules:
use_setstate_synchronously:
state_base_classes: []
Option Type Default Description
state_base_classes list [] Additional base classes to treat as a State

To disable this rule:

many_lints.yaml
rules:
use_setstate_synchronously: false

To keep the rule on but skip certain paths, use per-rule exclude.