avoid_passing_build_context_to_blocs
v0.4.0 Warning Bloc / Riverpod
This rule flags a BuildContext parameter on any constructor or method of a Bloc or Cubit. Positional and named parameters are both reported.
Why use this rule
Section titled “Why use this rule”A BuildContext is only valid while its element is mounted. A Bloc typically outlives the widget that created it — it sits in a BlocProvider above the route, or in a MultiBlocProvider at the app root — so the context it was handed goes stale, and the next Navigator.of(context) throws from inside business logic, far from the widget that caused it.
It also makes the Bloc untestable in isolation: blocTest cannot supply a real context, so every test needs a widget tree.
Whatever the context was for — navigating, showing a snackbar, reading the theme — belongs in the widget, driven by the state the Bloc emits.
See also: Bloc best practices
Examples
Section titled “Examples”Navigating from inside the bloc
Section titled “Navigating from inside the bloc”// Don't — `context` is stale by the time login finishesimport 'package:bloc/bloc.dart';import 'package:flutter/widgets.dart';
sealed class AuthEvent {}
class LoginRequested extends AuthEvent {}
class AuthBloc extends Bloc<AuthEvent, bool> { AuthBloc(this.context) : super(false) { // LINT on `context` on<LoginRequested>((event, emit) async { emit(true); await Navigator.of(context).pushNamed('/home'); }); }
final BuildContext context;}Emit the outcome and let the widget navigate, where the context is guaranteed live:
// Doimport 'package:bloc/bloc.dart';
sealed class AuthEvent {}
class LoginRequested extends AuthEvent {}
class AuthBloc extends Bloc<AuthEvent, bool> { AuthBloc() : super(false) { on<LoginRequested>((event, emit) => emit(true)); }}
// In the widget:// BlocListener<AuthBloc, bool>(// listener: (context, loggedIn) {// if (loggedIn) Navigator.of(context).pushNamed('/home');// },// child: const LoginForm(),// )A method parameter counts too
Section titled “A method parameter counts too”The context does not have to be stored — taking one at all is reported:
// Don'timport 'package:bloc/bloc.dart';import 'package:flutter/widgets.dart';
class SettingsCubit extends Cubit<bool> { SettingsCubit() : super(false);
void applyTheme(BuildContext context) { // LINT on `context` emit(MediaQuery.of(context).platformBrightness == Brightness.dark); }}// Do — take the value, not the context that produces itimport 'package:bloc/bloc.dart';
class SettingsCubit extends Cubit<bool> { SettingsCubit() : super(false);
void applyTheme({required bool isDark}) => emit(isDark);}
// In the widget:// context.read<SettingsCubit>().applyTheme(// isDark: MediaQuery.of(context).platformBrightness == Brightness.dark,// );Named parameters are reported
Section titled “Named parameters are reported”// Don'timport 'package:bloc/bloc.dart';import 'package:flutter/widgets.dart';
sealed class CheckoutEvent {}
class CheckoutBloc extends Bloc<CheckoutEvent, int> { CheckoutBloc({required BuildContext context}) : super(0); // LINT}Known limitations
Section titled “Known limitations”The parameter type must be exactly BuildContext. A bloc that takes a wrapper carrying a context (class NavigationService { final BuildContext context; }) has the same lifetime hazard but no BuildContext parameter to match, so it is not reported.
Configuration
Section titled “Configuration”This rule is in the recommended preset, so it is on with
preset: recommended or preset: opinionated. Add it to preset: core with
avoid_passing_build_context_to_blocs: true.
To turn it off:
rules: avoid_passing_build_context_to_blocs: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_build_context_in_providers— Providers outlive widgets, so they should not receive a BuildContext.never_discard_build_context— Don’t discard a BuildContext parameter with a wildcard.use_closest_build_context— Use the inner BuildContext from builder callbacks, not the outer one.avoid_passing_bloc_to_bloc— Prevent Bloc/Cubit classes from depending on other Bloc/Cubit instances.