Skip to content

avoid_duplicate_cascades

v0.4.0 Warning Fix Control Flow

Flags a cascade section that repeats an earlier one exactly — the same assignment with the same value, or the same call with the same arguments.

See also: Cascade notation

A long cascade is built by copying the line above and editing it, and one edit gets missed:

class RequestBuilder {
String url = '';
String method = '';
int timeoutMs = 0;
void header(String name, String value) {}
}
RequestBuilder build() {
return RequestBuilder()
..url = '/orders'
..method = 'POST'
..header('accept', 'application/json')
..header('accept', 'application/json')
..timeoutMs = 5000;
}

Either drop the repeat, or supply the value that was meant:

class RequestBuilder {
String url = '';
String method = '';
int timeoutMs = 0;
void header(String name, String value) {}
}
RequestBuilder build() {
return RequestBuilder()
..url = '/orders'
..method = 'POST'
..header('accept', 'application/json')
..header('content-type', 'application/json')
..timeoutMs = 5000;
}

A repeated assignment with the same value is dead. A repeated assignment with a different value is legal and never reported, so the rule does not stop you from overwriting on purpose:

class Config {
String name = '';
}
void demo() {
// Don't — the second write changes nothing
final a = Config()
..name = 'test'
..name = 'test';
// Fine — the second write is the one that matters
final b = Config()
..name = 'draft'
..name = 'final';
}

For a method the duplicate is worse than dead code: it runs twice. Two add calls on a list mean two elements:

void demo() {
final numbers = <int>[]
..add(1)
..add(1); // LINT — and `numbers` really does hold [1, 1]
}

If the repetition is deliberate, write it in a way that says so — a loop, or two distinct calls — rather than relying on the reader to notice.

Duplicates are matched on source text, not on meaning. ..name = 'a' and ..name = "a" are different keys and neither is reported; so are ..header('x', y) and ..header('x', y as String).

The comparison is per cascade expression. Two identical sections in two separate cascades on the same object are not compared with each other.

The report lands on the second occurrence, and the quick fix removes that section. When the same section appears three times, the second and third are each reported.

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

To turn it off:

many_lints.yaml
rules:
avoid_duplicate_cascades: false

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