Typical mistakes and error messages
Most Provider errors come from the same three roots: the wrong `context`, the wrong lifetime, the wrong kind of read. Recognising the error message saves time both in interviews and in practice.
| Error | Cause | Fix |
|---|---|---|
| `ProviderNotFoundException` — "Could not find the correct Provider<T> above this widget" | The read uses a `context` that has no such provider above it (for example the context of the widget that creates the provider, or a dialog/route context outside it) | Move the provider higher, or obtain a new `context` for the subtree via a `Builder` or a separate widget |
| "A ChangeNotifier was used after being disposed" | An existing object was handed to `create` and the provider disposed it; or an async operation returns after disposal and calls `notifyListeners()` | Use `.value`; after async work, check the object is still alive |
| "setState() or markNeedsBuild() called during build" | `notifyListeners()` fires during `build` — for instance a method is invoked from inside `build` | Move the load to `initState`/`didChangeDependencies`, or defer it by one frame |
| The UI never updates | `read` was used in `build`; or `notifyListeners()` was never called; or `select` returns a mutable value | Switch to `watch`/`Consumer`; select an immutable value |
There is a useful detail in the Provider docs: if you make the type nullable (context.watch<Model?>()), no exception is thrown when the provider is absent — you get null. It is meant for optional providers, but using it to hide a ProviderNotFoundException just makes the bug silent. Knowing that nuance shows attention to detail in an interview.
// ❌ showDialog-un builder-i başqa (Navigator-un overlay) context-i alır;
// provider bu context-dən yuxarıda olmaya bilər → ProviderNotFoundException.
void _confirm(BuildContext context) {
showDialog(
context: context,
builder: (dialogContext) => AlertDialog(
content: Text(dialogContext.watch<CartModel>().summary),
),
);
}
// ✅ Variant 1: dəyəri dialoq açılmadan əvvəl oxumaq.
void _confirm(BuildContext context) {
final summary = context.read<CartModel>().summary;
showDialog(
context: context,
builder: (_) => AlertDialog(content: Text(summary)),
);
}
// ✅ Variant 2: mövcud modeli dialoq ağacına .value ilə ötürmək.
void _confirm(BuildContext context) {
final cart = context.read<CartModel>();
showDialog(
context: context,
builder: (_) => ChangeNotifierProvider.value(
value: cart,
child: const CartDialog(),
),
);
}The most common case: the provider is not found inside a dialog.
📚 Sources and documentation
- package:provider — errors and FAQofficialpub.dev
ProviderNotFoundException, the nullable-type trick and the DO/DON'T list are in the README.
- BuildContext and creating dependenciesofficialapi.flutter.dev
Returning null when no matching widget is found, and the initState prohibition, are documented here.
- ChangeNotifier: disposeofficialapi.flutter.dev