avoid_unassigned_stream_subscriptions
Flags Stream.listen() calls whose return value (a StreamSubscription) is not assigned to a variable, returned, or passed as an argument. Without storing the subscription, you have no way to cancel it later, which leads to memory leaks and unexpected behavior.
Why use this rule
Section titled “Why use this rule”A StreamSubscription that is never stored cannot be cancelled. The listener keeps running indefinitely, holding references to the callback closure and everything it captures. This is especially problematic in StatefulWidgets where the stream may outlive the widget, causing setState() calls on a disposed State.
See also: Dart - Streams | StreamSubscription | Dart lint: cancel_subscriptions
void example() { final stream = Stream.fromIterable([1, 2, 3]);
// Subscription not assigned -- cannot cancel later stream.listen((event) { print(event); });}void example() { final stream = Stream.fromIterable([1, 2, 3]);
// Assigned to a variable -- can be cancelled later final subscription = stream.listen((event) { print(event); }); subscription.cancel();}
// Returning the subscription is also fine:StreamSubscription<int> listen(Stream<int> stream) { return stream.listen((event) => print(event));}
// Passing as an argument is also fine:void track(List<StreamSubscription> subs, Stream<int> stream) { subs.add(stream.listen((event) => print(event)));}Turning this rule off
Section titled “Turning this rule off”This rule is in the core preset, so it is on with preset: core,
preset: recommended or preset: opinionated.
To turn it off:
rules: avoid_unassigned_stream_subscriptions: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_unassigned_stream_subscriptions: ignored_instances: [eventBus]rules: avoid_unassigned_stream_subscriptions: ignored_instances: [eventBus]| Option | Type | Default | Description |
|---|---|---|---|
ignored_instances |
list of strings | [] |
Receiver expressions whose subscriptions are torn down centrally |
Related rules
Section titled “Related rules”always_remove_listener— Ensure every addListener() has a matching removeListener() in dispose().avoid_late_final_reassignment— Flag alate finalfield assigned twice on one path.avoid_unremovable_callbacks_in_listeners— Don’t pass an inline closure to addListener.dispose_fields— Ensure State fields with disposal methods are cleaned up in dispose().