avoid_duplicate_collection_elements
This rule is in the pedantic preset.
Flags a list literal that contains the same element twice, and a spread or if element repeated in any literal. The quick fix removes the duplicate, keeping the first occurrence.
A repeated constant in a hand-written list is almost always a typo for a third value — nothing fails, the list just carries the entry twice:
enum Permission { read, write, delete }
const defaultPermissions = <Permission>[ Permission.read, Permission.write, Permission.read,];enum Permission { read, write, delete }
const defaultPermissions = <Permission>[ Permission.read, Permission.write, Permission.delete,];A spread written twice
Section titled “A spread written twice”Spreading the same source twice either duplicates every value or is dead weight. This is the shape a merge conflict resolution leaves behind:
// Don'tfinal visible = [...pinnedItems, ...pinnedItems, ...recentItems];
// Dofinal visible = [...pinnedItems, ...recentItems];Spreads are checked inside sets and maps too, since the analyzer does not catch those:
// Don'tfinal allFlags = {...baseFlags, ...baseFlags};
// Dofinal allFlags = {...baseFlags, ...overrideFlags};An if element copy-pasted
Section titled “An if element copy-pasted”Two identical if elements guard on the same condition and emit the same value — usually the second was meant to test the other branch:
// Don'tfinal rows = [ if (isAdmin) 'Manage users', if (isAdmin) 'Manage users',];
// Dofinal rows = [ if (isAdmin) 'Manage users', if (!isAdmin) 'Request access',];Skipping repeated literals only
Section titled “Skipping repeated literals only”Padding lists and gradient stops legitimately repeat plain values. ignore_literals: true exempts them while still reporting a duplicated identifier or property access:
rules: avoid_duplicate_collection_elements: ignore_literals: true// Accepted — plain literalsconst padding = [0, 0, 0, 0];
// Still reported — a repeated named constantconst sizes = [Spacing.small, Spacing.small];Known limitations
Section titled “Known limitations”Only stable elements are compared. Elements are matched by source text, which is sound only for a literal, an identifier, or a property access. A constructor call is never compared, so [Locale('en'), Locale('en')] is not reported — nor is [next(), next()], since two calls may legitimately return different values. The same holds for spreads: [...fetch(), ...fetch()] is left alone.
Plain values in sets and maps are out of scope. The analyzer already reports duplicate set elements and duplicate map keys natively, so covering them here would double-report. Only spreads and if elements are checked in those literals.
Turning this rule off
Section titled “Turning this rule off”This rule appears only in the pedantic preset because repeated values and
actions are common in fixtures, ordered scenarios, gradients and other
intentionally positional lists.
Enable it by name:
rules: avoid_duplicate_collection_elements: trueTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_duplicate_collection_elements: ignore_literals: truerules: avoid_duplicate_collection_elements: ignore_literals: true| Option | Type | Default | Description |
|---|---|---|---|
ignore_literals |
bool | false |
Skip repeated literals ([0, 0, 0]), still reporting duplicated identifiers and property accesses |
Related rules
Section titled “Related rules”avoid_collection_equality_checks— Avoid comparing collections with == or != as it checks reference equality, not contents.avoid_collection_methods_with_unrelated_types— Avoid calling collection methods with arguments whose types are unrelated to the collection’s type parameter.avoid_unsafe_collection_methods— Check for emptiness before using first, last, single or reduce.avoid_accessing_collections_by_constant_index— Avoid accessing a collection by a constant index inside a loop.