avoid_ref_inside_state_dispose
v0.4.0 Warning Riverpod State
This rule catches ref usage inside the dispose() method of ConsumerState classes. By the time dispose() runs, providers may already be torn down, so reading or watching them can throw unexpected errors or return stale data.
Why use this rule
Section titled “Why use this rule”In Riverpod, the lifecycle of providers and widgets is not tightly coupled. When dispose() fires, there is no guarantee that the providers you are trying to access are still alive. Accessing ref in dispose() can silently read disposed state or throw UnmountedRefException, leading to hard-to-debug crashes in production.
See also: Riverpod automatic disposal
class MyWidgetState extends ConsumerState<ConsumerStatefulWidget> { @override void dispose() { // ref may already be invalid at this point ref.read(someProvider); super.dispose(); }
@override Widget build(BuildContext context) => const SizedBox();}class MyWidgetState extends ConsumerState<ConsumerStatefulWidget> { @override void dispose() { // Clean up without accessing ref super.dispose(); }
@override Widget build(BuildContext context) { // ref is safe to use in build final value = ref.watch(someProvider); return Text(value); }}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_ref_inside_state_dispose: true.
To turn it off:
rules: avoid_ref_inside_state_dispose: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_ref_read_inside_build— Subscribe in build; do not read once.avoid_ref_watch_outside_build— Subscribe only in build; read once everywhere else.use_ref_and_state_synchronously— Check ref.mounted before using ref or state after an await.async_value_nullable_pattern— Matching AsyncValue(:final value?) on a nullable value hides a legitimate null result.