avoid_late_context
This rule flags a late field inside a State whose initializer reads context. The value is computed once, at an unpredictable moment, and then never updates.
Why use this rule
Section titled “Why use this rule”A late field initializes on first access. Inside a State that is usually during build, but nothing guarantees it — if the field is first touched from initState, the inherited-widget lookup runs before the element is mounted and throws.
The quieter problem is worse. A late field initializes exactly once. A value derived from Theme.of(context) or MediaQuery.of(context) freezes at whatever it was on first access and then ignores every later change: a theme switch, a rotation, a locale change, a parent rebuilding with new data. The UI keeps rendering stale values with nothing to indicate why.
Inherited widgets are designed to be read where they can be re-read — in build, or in didChangeDependencies when the value must be cached.
See also: Flutter: BuildContext, State.didChangeDependencies
class _MyState extends State<MyWidget> { late final theme = Theme.of(context); // frozen after first access}Read it in build, where it re-reads on every rebuild:
class _MyState extends State<MyWidget> { @override Widget build(BuildContext context) { final theme = Theme.of(context); return Text('hi', style: theme.textTheme.bodyMedium); }}When the value really must be cached, use didChangeDependencies, which Flutter calls again whenever an inherited dependency changes:
class _MyState extends State<MyWidget> { late ThemeData _theme;
@override void didChangeDependencies() { super.didChangeDependencies(); _theme = Theme.of(context); }}Known limitations
Section titled “Known limitations”Only fields inside a State are checked, since elsewhere context is not the ambient widget context this rule is about. Classes that act as state without extending State can be included with the shared state_base_classes option.
Static fields are skipped, and so are late fields with no initializer — those are assigned explicitly, where the author controls the timing.
The initializer must mention context by name and resolve to a BuildContext, so an unrelated local named context does not trigger the rule.
Turning this rule off
Section titled “Turning this rule off”This rule is in the recommended preset, so it is on with
preset: recommended or preset: opinionated. Add it to preset: core with
avoid_late_context: true.
To turn it off:
rules: avoid_late_context: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”Projects with a state abstraction that does not extend Flutter’s State can
opt that base class into this rule:
many_lints: rules: avoid_late_context: state_base_classes: [AppState]rules: avoid_late_context: state_base_classes: [AppState]| Option | Type | Default | Description |
|---|---|---|---|
state_base_classes |
list of strings | [] |
Additional non-State base classes whose subclasses should be treated as state classes |
Related rules
Section titled “Related rules”avoid_empty_setstate— Don’t call setState with an empty callback.avoid_inherited_widget_in_initstate— Don’t look up inherited widgets inside initState.avoid_mounted_in_setstate— Detect mounted checks inside setState callbacks.avoid_state_constructors— Avoid constructors with logic in State classes.