Skip to content

provider_parameters

v0.8.0 Warning Riverpod State

Flags an argument passed to a family provider that has no stable equality — a non-const collection literal, a closure, or an instance of a class that does not override ==.

Riverpod caches one provider instance per family argument, keyed by ==. An argument that allocates a new object on every build never compares equal to the previous one, so Riverpod treats each rebuild as a brand-new provider: the old one is disposed, state is lost, and any network request behind it runs again. The symptom is an infinite rebuild loop or a widget that never keeps its data — both hard to trace back to the argument.

See also: Riverpod families

// A new list every build — never equal to the last one
ref.watch(myProvider([1, 2, 3]));
// A new closure every build
ref.watch(myProvider(() => 42));
// Foo does not override ==, so each instance is distinct
ref.watch(myProvider(Foo()));
class Foo {
const Foo(this.id);
final int id;
@override
bool operator ==(Object other) => other is Foo && other.id == id;
@override
int get hashCode => id.hashCode;
}
void watchStableValues(WidgetRef ref) {
// Const values are canonicalized, so equality holds.
ref.watch(myProvider(const [1, 2, 3]));
ref.watch(myProvider(const Foo(1)));
// Primitives compare by value.
ref.watch(myProvider(42));
}

This rule is in the recommended preset, so it is on with preset: recommended or preset: opinionated. Add it to preset: core with provider_parameters: true.

To turn it off:

many_lints.yaml
rules:
provider_parameters: false

To keep the rule on but skip certain paths, use per-rule exclude.