Solución: LateInitializationError: Field '...' has not been initialized en Flutter
Corrige lecturas de campos late sin inicializar en Flutter: inicialización síncrona o estados de carga, error y datos con código probado.
Este sitio utiliza a Walter, un agente de IA, para investigar, redactar y mantener el contenido. Proceso editorial y de verificación
Leer un campo late sin asignar produce LateInitializationError. Busca la lectura en el primer frame de tu propio código y comprueba qué ruta debía asignar el campo antes. late no espera a que termine una operación asíncrona. Los ejemplos se comprobaron con Flutter 3.44.8 y Dart 3.12.2.
Reproducir el error
Este programa compila, pero falla al leer name:
class Profile {
late String name;
}
void main() {
print(Profile().name);
}
La VM de Dart muestra LateInitializationError: Field 'name' has not been initialized. Es un diagnóstico, no el nombre de una clase pública de dart:core que debas importar o capturar. Corrige la inicialización que falta.
Representar carga, error y datos
Una petición iniciada en initState() puede seguir pendiente durante el primer build(). Este widget completo usa estado nullable y maneja éxito y error. Pasa tu función asíncrona como loadName:
import 'package:flutter/material.dart';
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key, required this.loadName});
final Future<String> Function() loadName;
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
String? _name;
Object? _error;
@override
void initState() {
super.initState();
_load();
}
Future<void> _load() async {
try {
final name = await widget.loadName();
if (!mounted) return;
setState(() => _name = name);
} catch (error) {
if (!mounted) return;
setState(() => _error = error);
}
}
@override
Widget build(BuildContext context) {
if (_error != null) return Text('Failed: $_error');
final name = _name;
if (name == null) return const CircularProgressIndicator();
return Text(name);
}
}
El ejemplo carga una vez por instancia de State. Si la petición depende de entradas cambiantes del widget, trata sus cambios en didUpdateWidget o usa un widget/proveedor con la clave adecuada. Las comprobaciones de mounted evitan actualizar un estado eliminado; no cancelan la petición. También sirven FutureBuilder con un Future almacenado o AsyncValue. El propio campo que contiene un Future puede ser late final si se asigna antes de leerlo; su resultado puede llegar después.
Elegir la inicialización según la dependencia
- Valor síncrono: asígnalo antes de leerlo, normalmente en
initState()si necesitawidget. Libera también unTextEditingControllerendispose(). - Valor diferido:
late final value = compute();ejecuta el inicializador en el primer acceso. Un inicializador late de instancia puede acceder a miembros de la instancia, incluidowidgeten unState; el primer acceso debe ocurrir en el momento apropiado del ciclo de vida. El inicializador aún puede fallar o ser recursivo. - Dependencia heredada: las llamadas que registran una dependencia, como
Theme.of(context), corresponden abuild()odidChangeDependencies(), no ainitState(). Este último hook se ejecuta antes del primer build y cuando cambian las dependencias. La restricción afecta al registro de dependencias, no a todo uso decontext.
Errores parecidos y soluciones engañosas
Asignar dos veces un campo late final produce la variante «already initialized». Elimina la asignación duplicada o usa un campo mutable si la reasignación es intencionada. late no desactiva todas las comprobaciones del analizador: Dart detecta variables locales late que definitivamente no están asignadas y algunas asignaciones repetidas a locales late final. Las comprobaciones en ejecución siguen siendo necesarias cuando el análisis estático no basta. No son assertions exclusivas de depuración; el mensaje exacto puede variar según el backend y el modo de compilación.
El valor debe estar listo antes de leerlo, o el estado pendiente debe representarse explícitamente. Un await no vuelve incorrecto a late si todos los consumidores esperan primero a que esté listo; el problema es la lectura prematura del widget.
Corrección del 2 de noviembre de 2026: se corrigieron las afirmaciones sobre el analizador, el acceso diferido a miembros de instancia, las dependencias heredadas y los diagnósticos en release; se eliminó la referencia a una clase pública inexistente. El widget revisado se analizó y probó con éxito, error y eliminación.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.