The LateInitializationError in Flutter occurs when you declare a variable with the late keyword but fail to assign it a value before it’s used for the first time.
In simple terms, you’ve made a promise to Dart that a variable will have a value before you read from it, but that promise was broken.
Common Causes and Solutions
This error most often appears in a few common scenarios, especially within StatefulWidget classes.
1. Forgetting to Initialize in initState
A frequent mistake is declaring a late variable in a StatefulWidget‘s State class and then forgetting to initialize it inside the initState method.
Problem:
class _MyWidgetState extends State<MyWidget> {
late AnimationController _controller;
@override
Widget build(BuildContext context) {
// ERROR! _controller is used here before it's ever initialized.
return Transform.rotate(
angle: _controller.value,
child: const FlutterLogo(size: 100),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
Solution:
Initialize the variable in initState(), which is guaranteed to run before build().
class _MyWidgetState extends State<MyWidget> {
late AnimationController _controller;
@override
void initState() {
super.initState();
// Initialize the variable here
_controller = AnimationController(
vsync: this, // requires with TickerProviderStateMixin
duration: const Duration(seconds: 2),
);
}
@override
Widget build(BuildContext context) {
return Transform.rotate(
angle: _controller.value,
child: const FlutterLogo(size: 100),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
Dart2. Variable Initialized Conditionally
If the logic that initializes your late variable is inside a condition that doesn’t run, the variable will remain uninitialized.
Problem:
class User {
late String name;
void loadName(bool hasNetwork) {
if (hasNetwork) {
this.name = 'Flutter Dev'; // This line might not run!
}
}
}
void main() {
final user = User();
user.loadName(false); // We pass false
print(user.name); // ERROR! 'name' was never initialized.
}
DartSolution:
Ensure all code paths initialize the variable, or consider making the variable nullable (?) if its existence is truly optional.
class User {
String? name; // Use a nullable type instead
void loadName(bool hasNetwork) {
if (hasNetwork) {
this.name = 'Flutter Dev';
}
}
}
void main() {
final user = User();
user.loadName(false);
print(user.name); // Prints 'null' - no error
}
Dart3. Using late final without Immediate Initialization
A late final variable must be assigned a value exactly once. If you declare it without an immediate value, you must initialize it later (e.g., in a constructor or initState) before it’s used.
Problem:
class ApiConfig {
late final String apiKey;
ApiConfig() {
// Constructor finishes without initializing apiKey
}
void connect() {
print('Connecting with key: $apiKey'); // ERROR! apiKey has no value.
}
}
DartSolution:
Initialize the late final variable in the constructor or from another source before it’s accessed.
class ApiConfig {
late final String apiKey;
// Initialize via the constructor
ApiConfig(this.apiKey);
void connect() {
print('Connecting with key: $apiKey');
}
}
DartHow to Prevent This Error
- Initialize in
initState: For state-dependent data in aStatefulWidget,initStateis the perfect place for initialization. - Use Nullable Types (
?): If a variable is allowed to benull, declare it with a?(e.g.,String? name;) instead of usinglate. This is often a safer alternative. - Initialize in Constructor: If a variable is essential for a class to function, require it in the constructor.
- Check Your Logic: Before using a
latevariable, double-check that all possible code paths leading to it will assign it a value.