avoid_unsafe_collection_methods
v0.8.0 Warning Collection Type
This rule flags first, last, single and reduce used on a collection that has no emptiness check anywhere in the enclosing function.
Why use this rule
Section titled “Why use this rule”All four throw a StateError on an empty iterable. Because the throw originates in dart:core, the stack trace points at framework code rather than the line that made the assumption — and the failure only appears once real data happens to be empty, which is usually in production rather than in tests.
Dart offers direct replacements: firstOrNull, lastOrNull and singleOrNull from package:collection, or fold instead of reduce when a seed value makes sense.
String firstName(List<User> users) { // Throws when the list is empty return users.first.name;}
int total(List<int> amounts) { return amounts.reduce((a, b) => a + b);}String? firstName(List<User> users) { if (users.isEmpty) return null; return users.first.name;}
// Or use the null-returning variantString? firstNameOrNull(List<User> users) { return users.firstOrNull?.name;}
// fold supplies a seed, so an empty list is fineint total(List<int> amounts) { return amounts.fold(0, (a, b) => a + b);}Known limitations
Section titled “Known limitations”Detection is deliberately narrow, to keep false positives near zero:
- Only a directly named receiver is checked — a local, parameter, or field. A chained expression like
items.where(...).firsthas no name to match a guard against and is never reported. - Any emptiness check on that name anywhere in the function counts as a guard, even one in an unrelated branch. This over-accepts on purpose.
- A collection literal with elements (
[1, 2, 3].first) is treated as provably non-empty. singleWhereis excluded: it throws when no element matches, which an emptiness check would not prevent.
Configuration
Section titled “Configuration”This rule is in the opinionated preset, so it is on with
preset: opinionated, or by name:
rules: avoid_unsafe_collection_methods: trueTo turn it off again:
rules: avoid_unsafe_collection_methods: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_accessing_collections_by_constant_index— Avoid accessing a collection by a constant index inside a loop.prefer_safe_collection_access— list.first throws where list.head returns None.avoid_collection_methods_with_unrelated_types— Avoid calling collection methods with arguments whose types are unrelated to the collection’s type parameter.avoid_collection_equality_checks— Avoid comparing collections with == or != as it checks reference equality, not contents.