Short answer
Find the .first, .last, .single, reduce or firstWhere call on the first stack trace line in your own code. Check isEmpty before it, use firstOrNull (built into Dart 3) or firstWhereOrNull (import package:collection/collection.dart), or give firstWhere an orElse. Then decide what the screen shows when there is no item. The list is usually empty because data has not loaded yet, a filter matched nothing, or an id from a route or a link points to an item that was deleted.
Why the list is empty, and the fix
01
.first on a list that has not loaded
“The first element. Throws a StateError if this is empty.” Dart, Iterable.first
build reads items.first while items is still the empty list it started as. Check isEmpty, and show a loader or an empty state.
if (items.isEmpty) return const Text('No items yet'); final latest = items.first;02
firstWhere that matches nothing
“If no element satisfies test, the result of invoking the orElse function is returned. If orElse is omitted, it defaults to throwing a StateError.” Dart, Iterable.firstWhere
firstWhere((p) => p.id == id) throws when no item has that id: a deleted record, a stale id from a deep link or notification, or an int id compared with a String. Use firstWhereOrNull and handle null, or pass orElse.
import 'package:collection/collection.dart'; final product = products.firstWhereOrNull((p) => p.id == id); if (product == null) return const NotFoundScreen();03
.single, .last or reduce on the wrong count
“Throws a StateError if this is empty or has more than one element.” Dart, Iterable.single
.single throws on an empty list and on a list with two or more items (that one says Bad state: Too many elements). .last and reduce throw on an empty list too. Use them only where the count is guaranteed, such as right after a check, or use singleOrNull and lastOrNull.
04
await stream.first on a stream that closes empty
“If this stream is empty (a done event occurs before the first data event), the returned future completes with an error.” Dart, Stream.first
await stream.first fails with the same message when the stream closes before sending a value, for example a stream built from an empty list or a finished download. Use firstWhere with orElse on the stream, or listen and handle the done event.
Checked against the vendor’s docs on : Dart API: Iterable.first; Dart API: Iterable.firstWhere; Dart API: Iterable.single; Dart API: Stream.first; Dart API: StateError class.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Flutter “type 'Null' is not a subtype of type 'String'” · Flutter “Null check operator used on a null value” · Flutter LateInitializationError · Flutter “Looking up a deactivated widget’s ancestor is unsafe”