avoid-unsafe-collection-methods
- Group
- Correctness
- Path
lint/correctness/avoid-unsafe-collection-methods- Default
- Off, opt in
- Origin
- Falcon
- Rule
- 180 of 512
Flags potentially throwing element access on SDK collections.
Iterable first/last/single (including object-pattern getters), predicate
searches without an orElse fallback, elementAt, and List indexing can
throw when an element does not exist. The max/min extension getters are
included only when their resolved extension comes from package:collection.
Prefer nullable alternatives. Map indexing, unknown receivers, and custom
collection implementations are excluded. List indexing is safe in a resolved
Flutter ListView.builder/GridView.builder's direct, synchronous itemBuilder
body when itemCount is the same local list's length (including
list?.length ?? 0) and the index is its second parameter. Both bindings
must be unreassigned. The list must otherwise appear only as an index or
length receiver: aliases, helper arguments, method calls, setters and cascades
conservatively disable the exemption. Shadowed bindings and nested callbacks
do not inherit it. Other bounds/cardinality proofs are not attempted.
Invalid
import 'package:collection/collection.dart';
void access(List<int> values, Set<String> names, Iterable<int> items, int index) {
print(values.first);
print(names.last);
print(items.single);
print(values[index]);
print(items.elementAt(index));
print(values.firstWhere((value) => value > 0));
print(values.lastWhere((value) => value > 0));
print(values.singleWhere((value) => value > 0));
values..first;
values..firstWhere((value) => value > 0);
}
void objectPatterns(Object value) {
if (value case List<int>(first: final first)) {
print(first);
}
if (value case Iterable<int>(last: final last)) {
print(last);
}
if (value case Set<int>(single: final single)) {
print(single);
}
}
void packageExtrema(Iterable<int> values) {
print(values.max);
print(values.min);
values..max;
if (values case Iterable<int>(min: final smallest)) {
print(smallest);
}
}
class NotString {
List<int> split(String separator) => [];
}
void customSplit(NotString value) {
print(value.split(',').first);
print(value.split(',').last);
}
void mutatedSplit(String text) {
text.split(',')..clear()..first;
}
void splitResults(String text, Pattern separator) {
print(text.split(separator).first);
print(text.split(separator).last);
text.split(separator)..first..last;
print(''.split('').first);
print(''.split(RegExp('')).last);
}void access(List<int> values, Set<String> names, Iterable<int> items, int index) { print(values.first); print(values.first); print(names.last); print(names.last); print(items.single); print(items.single); print(values[index]); print(values[index]); print(items.elementAt(index)); print(items.elementAt(index)); print(values.firstWhere((value) => value > 0)); print(values.firstWhere((value) => value > 0)); print(values.lastWhere((value) => value > 0)); print(values.lastWhere((value) => value > 0)); print(values.singleWhere((value) => value > 0)); print(values.singleWhere((value) => value > 0)); values..first; values..first; values..firstWhere((value) => value > 0);void objectPatterns(Object value) { if (value case List<int>(first: final first)) { } if (value case Iterable<int>(last: final last)) { } if (value case Set<int>(single: final single)) {void packageExtrema(Iterable<int> values) { print(values.max); print(values.max); print(values.min); print(values.min); values..max; values..max; if (values case Iterable<int>(min: final smallest)) {void customSplit(NotString value) { print(value.split(',').first); print(value.split(',').first); print(value.split(',').last);void mutatedSplit(String text) { text.split(',')..clear()..first;void splitResults(String text, Pattern separator) { print(text.split(separator).first); print(text.split(separator).first); print(text.split(separator).last); print(text.split(separator).last); text.split(separator)..first..last; print(text.split(separator).last); text.split(separator)..first..last; text.split(separator)..first..last; print(''.split('').first); print(''.split('').first); print(''.split(RegExp('')).last);Valid
void access(List<int> values, Map<int, String> names, dynamic unknown) {
print(names[0]);
print(values.firstOrNull);
print(values.lastOrNull);
print(values.singleOrNull);
print(values.firstWhere((value) => value > 0, orElse: () => 0));
print(values.lastWhere((value) => value > 0, orElse: () => 0));
print(values.singleWhere((value) => value > 0, orElse: () => 0));
print(unknown.first);
}
class Custom {
int get first => 0;
int operator [](int index) => 0;
}
void custom(Custom value) { print(value.first); print(value[0]); }
class Splittable {
Custom split(String separator) => Custom();
}
void customSplit(Splittable value) {
print(value.split(',').first);
}
void customPatterns(Object value) {
if (value case Custom(first: final first)) {
print(first);
}
}
extension LocalExtrema on Iterable<int> {
int get max => 0;
int get min => 0;
}
void localExtrema(Iterable<int> values) {
print(values.max);
print(values.min);
if (values case Iterable<int>(max: final maximum)) {
print(maximum);
}
}Configure avoid-unsafe-collection-methods
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"avoid-unsafe-collection-methods": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/avoid-unsafe-collection-methods: <reason>More correctness rules
- avoid-unsafe-reduce
Warn when SDK Iterable.reduce can receive an empty collection.
- avoid-unused-after-null-check
Reports a null-checked local ignored by a branch that passes another local of the same resolved type to a call.
- avoid-unused-parameters
avoid-unused-parametersrecommendedDisallow declared parameters that are never used, excluding primary constructors.
- avoid-watch-outside-buildrecommendedprovider
Flags listening Provider accesses proven to run outside Flutter builds.
- avoid-web-libraries-in-flutter
avoid_web_libraries_in_flutterrecommendedflutterDisallow importing web-only
dart:libraries from Flutter code. - await-only-futures
await_only_futuresrecommendedAwait only values assignable to futures;
FutureOr, dynamic, bottom types and extension types are accepted like the analyzer. - banned-importscross-file
Report imports forbidden by package-relative architectural boundaries.
- cancel-subscriptions
cancel_subscriptionsrecommendedCancel instances of
dart:asyncStreamSubscription.