dispose_provided_instances
This rule flags instances created inside Riverpod provider callbacks or Notifier build() methods that have a dispose(), close(), or cancel() method but are not cleaned up via ref.onDispose(). It recognizes tear-off, lambda, and block body cleanup patterns.
Why use this rule
Section titled “Why use this rule”When a provider creates a disposable resource (like a controller, stream subscription, or service with a close() method) without registering cleanup, the resource leaks when the provider is destroyed. This leads to memory leaks and resource exhaustion over time. The ref.onDispose() callback ensures proper cleanup regardless of how or when the provider is disposed.
See also: Riverpod automatic disposal
import 'package:flutter_riverpod/flutter_riverpod.dart';import 'package:riverpod/riverpod.dart';
class DisposableService { void dispose() {} String get value => 'hello';}
// Instance has dispose() but ref.onDispose is not calledfinal badProvider = Provider<DisposableService>((ref) { final instance = DisposableService(); return instance;});
// Notifier build() creates disposable without ref.onDisposeclass BadNotifier extends Notifier<DisposableService> { @override DisposableService build() { final instance = DisposableService(); return instance; }}import 'package:flutter_riverpod/flutter_riverpod.dart';import 'package:riverpod/riverpod.dart';
class DisposableService { void dispose() {} String get value => 'hello';}
// Using ref.onDispose with tear-offfinal goodProvider = Provider<DisposableService>((ref) { final instance = DisposableService(); ref.onDispose(instance.dispose); return instance;});
// Using ref.onDispose with lambdafinal goodLambdaProvider = Provider<DisposableService>((ref) { final instance = DisposableService(); ref.onDispose(() => instance.dispose()); return instance;});
// Notifier build() with ref.onDisposeclass GoodNotifier extends Notifier<DisposableService> { @override DisposableService build() { final instance = DisposableService(); ref.onDispose(instance.dispose); return instance; }}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
dispose_provided_instances: true.
To turn it off:
rules: dispose_provided_instances: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: dispose_provided_instances: additional_cleanup_methods: [release, shutdown]rules: dispose_provided_instances: additional_cleanup_methods: [release, shutdown]| Option | Type | Default | Description |
|---|---|---|---|
cleanup_methods |
list of strings | [dispose, close, cancel] |
Replaces the cleanup method names the rule looks for |
additional_cleanup_methods |
list of strings | [] |
Extends whichever list applies |
Order matters: it is the priority used when a type declares more than one
cleanup method. Names added via additional_cleanup_methods are appended, so a
project’s own release() is only chosen when the type declares no standard
cleanup method.
Both options apply to detection and recognition — a method listed here counts
both as “this instance needs disposing” and as “this ref.onDispose disposes it”.
Related rules
Section titled “Related rules”dispose_fields— Ensure State fields with disposal methods are cleaned up in dispose().always_remove_listener— Ensure every addListener() has a matching removeListener() in dispose().avoid_unremovable_callbacks_in_listeners— Don’t pass an inline closure to addListener.emit_new_bloc_state_instances— Emit a new state instance instead of the existing state object.