prefer_immutable_bloc_state
v0.4.0 Warning Fix Bloc / Riverpod
This rule flags a Bloc or Cubit state class that is missing the @immutable annotation. The state class is recognised through the type argument of Bloc<Event, State> or Cubit<State>, and the check is then widened to every subclass and implementor.
This rule is in the opinionated preset.
Why use this rule
Section titled “Why use this rule”emit compares the new state against the current one and does nothing when they are equal. Mutating a state object in place therefore produces a state change no listener ever sees — the reference did not change, so emit discards it. The UI simply does not update, with no error to trace back to.
@immutable moves that failure to analysis time: the analyzer reports a non-final field where it is declared, rather than leaving the bug to be found in a running app.
See also: Bloc state management
Not for Riverpod or plain state classes
Section titled “Not for Riverpod or plain state classes”This rule recognises state by type, so it is completely inert in a project without the bloc package.
If you want the same advice for Riverpod notifier state, or for any class your project names ...State, use prefer_immutable_state instead. It matches on the class name and carries the name_pattern option.
Until v0.10.0 this rule did both, which meant a Riverpod-only codebase received “Bloc state” diagnostics for every class merely named ...State. Splitting them means each rule now says what it actually checks.
import 'package:bloc/bloc.dart';
sealed class CounterState {}
class CounterInitial extends CounterState {}
class CounterCubit extends Cubit<CounterState> { CounterCubit() : super(CounterInitial());}import 'package:bloc/bloc.dart';import 'package:meta/meta.dart';
@immutablesealed class CounterState {}
@immutableclass CounterInitial extends CounterState {}
class CounterCubit extends Cubit<CounterState> { CounterCubit() : super(CounterInitial());}Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: prefer_immutable_bloc_state: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”emit_new_bloc_state_instances— Emit a new state instance instead of the existing state object.avoid_duplicate_bloc_event_handlers— Register each bloc event type exactly once.handle_bloc_event_subclasses— Register a handler for every Bloc event subclass.avoid_bloc_public_methods— Prevent public methods, getters, and setters in Bloc classes.