never_discard_build_context
v1.0.0 Warning Fix Widget Best Practices
This rule is in the pedantic preset.
This rule flags a BuildContext parameter named with a wildcard — _, __, and so on. Discarding the parameter throws away the closest context, which is usually the only correct one to use.
Why use this rule
Section titled “Why use this rule”Discarding a context does not remove the need for one. The body still has to look things up, so it reaches for a context from an enclosing scope — and that context sits higher in the widget tree.
That difference is not cosmetic. Theme.of, MediaQuery.of and Navigator.of walk up from the element they are given, so an outer context resolves against a different subtree. The consequences are real:
- A
ThemeorMediaQueryintroduced between the two contexts is skipped entirely, so you silently read the ancestor’s values. Navigator.ofmay find the wrong navigator in a nested-navigator layout.- If the outer element is deactivated while the callback is still alive, the lookup throws.
The failure mode is what makes this worth linting: the code compiles, and usually appears to work, right up until someone inserts a widget between the two contexts.
See also: BuildContext API docs, Flutter: of accessors and BuildContext
// The builder's own context is discarded, so `Theme.of` runs against the// outer context and skips any theme introduced in between.Widget build(BuildContext context) { return Builder( builder: (_) => Text('hi', style: Theme.of(context).textTheme.bodyMedium), );}Widget build(BuildContext context) { return Builder( builder: (innerContext) => Text('hi', style: Theme.of(innerContext).textTheme.bodyMedium), );}Quick fix
Section titled “Quick fix”Name the parameter context renames the wildcard so the parameter becomes usable.
The fix is deliberately withheld when something named context is already in scope — most often the enclosing build method’s own parameter. Renaming there would shadow that name and change which element the existing lookups in the body resolve against, so the rule still reports but leaves the choice of name to you.
Known limitations
Section titled “Known limitations”Only an exact BuildContext is reported. A subclass is left alone, since renaming a parameter with its own meaning is not obviously right.
A name such as _context is not a discard — it is a private name that remains usable — and is not reported.
Configuration
Section titled “Configuration”This rule appears only in the pedantic preset because builders that perform
no inherited lookup can legitimately discard their context.
rules: never_discard_build_context: trueTo turn it off again:
rules: never_discard_build_context: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”use_closest_build_context— Use the inner BuildContext from builder callbacks, not the outer one.avoid_build_context_in_providers— Providers outlive widgets, so they should not receive a BuildContext.avoid_passing_build_context_to_blocs— Prevent passing BuildContext to Bloc or Cubit classes.avoid_too_many_widgets_per_build— Keep one build method within a widget budget.