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
A theme cached in a late final field. It initializes the first time build
touches it and then never changes — flip the app to dark mode and this widget
keeps painting the light palette:
class _CardState extends State<Card> { late final ThemeData _theme = Theme.of(context);
@override Widget build(BuildContext context) => Text(widget.title, style: _theme.textTheme.titleLarge);}The same field read from initState fails harder — the element is not mounted
yet, so the lookup throws:
class _CardState extends State<Card> { final Analytics _analytics = Analytics();
late final ThemeData _theme = Theme.of(context);
@override void initState() { super.initState(); _analytics.screenOpened(_theme.brightness.name); // throws here }
@override Widget build(BuildContext context) => Text(widget.title);}Read it in build, where it re-reads on every rebuild:
class _CardState extends State<Card> { @override Widget build(BuildContext context) { final theme = Theme.of(context); return Text(widget.title, style: theme.textTheme.titleLarge); }}When the value must be cached, use didChangeDependencies — Flutter calls it
again whenever an inherited dependency changes, so the cache stays current:
class _CardState extends State<Card> { late ThemeData _theme;
@override void didChangeDependencies() { super.didChangeDependencies(); _theme = Theme.of(context); }
@override Widget build(BuildContext context) => Text(widget.title, style: _theme.textTheme.titleLarge);}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:
class _CardState extends State<Card> { late ThemeData _theme; // not reported — nothing runs at first access
@override void didChangeDependencies() { super.didChangeDependencies(); _theme = Theme.of(context); }
@override Widget build(BuildContext context) => Text(widget.title);}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.