Kotlin Error: Variable must be initialized
In this tutorial, we shall learn how to handle Kotlin Compilation Error Variable must be initialized. Usually, this compilation error occurs when we try to access a variable (or its methods) which is declared but not initialized.
In Kotlin, a local variable must have a definite value before it is read. A declaration such as var name: String only tells the compiler the variable type. It does not create a usable String value. Therefore, calling name.length, adding items to an unassigned list, or returning an unassigned variable causes this compile-time error.
This rule is intentional. Kotlin avoids many accidental null and uninitialized-value errors by checking variable assignment at compile time. The fix is to assign a value before first use, make the value nullable when absence is valid, initialize a class property in the constructor, or use lateinit only for supported mutable properties that are assigned later.
When Kotlin says a variable must be initialized
You will commonly see Variable must be initialized in these situations:
- A local variable is declared inside a function but used before an assignment.
- A
valorvarproperty in a class has no initializer and is not assigned in every constructor path. - A variable is assigned only inside a conditional branch, loop, lambda, or
tryblock, so the compiler cannot prove that assignment always happens. - A non-null type such as
StringorMutableList<User>is declared without a value, even though Kotlin requires non-null values to be available before use.
Reproduce the Error: Variable must be initialized
In the below example, we have declared variable “users” of type ArrayList but not initialized. When we try to add an element to the list, it throws compilation error saying that the variable is not initialized, which is true. We have only declared, but not initialized the variable “users”.
The example also declares name without assigning a string value and then tries to access name.length. Depending on the Kotlin version and IDE checks, you may also see a message about generic type arguments for ArrayList. The initialization problem is that both name and users are read before a value is assigned.
example.kt
import java.util.ArrayList
fun main(args: Array) {
var name: String
name.length
var users: ArrayList
users.add(User("Suresh",25))
users.add(User("Mama",22))
println(users[0])
}
data class User(val name: String = "", val age: Int = 0)
Output
Error:(5, 4) Variable 'name' must be initialized
Error:(5, 9) Expression 'length' of type 'Int' cannot be invoked as a function. The function 'invoke()' is not found
Error:(7, 4) Variable 'users' must be initialized
Fix Kotlin Compilation Error Variable must be initialized
We shall try initializing the two variables “name” and “users” and run the program once again.
example.kt
import java.util.ArrayList
fun main(args: Array) {
var name: String = "NoName"
name.length
var users: ArrayList = ArrayList()
users.add(User("Suresh",25))
users.add(User("Mama",22))
println(users[0])
}
data class User(val name: String = "", val age: Int = 0)
Output
User(name=Suresh, age=25)
The fix is simple: assign a valid value before the variable is used. In everyday Kotlin code, you would usually prefer explicit generic types or Kotlin collection builders instead of a raw ArrayList.
fun main() {
val name: String = "NoName"
println(name.length)
val users: MutableList<User> = mutableListOf()
users.add(User("Suresh", 25))
users.add(User("Mama", 22))
println(users[0])
}
data class User(val name: String = "", val age: Int = 0)
Output
6
User(name=Suresh, age=25)
Use val, var, nullable type, or lateinit based on how the Kotlin variable is assigned
The right fix depends on what the variable represents. Do not use the same workaround everywhere. Pick the declaration that matches the lifecycle of the value.
| Kotlin situation | Recommended declaration | Why it fixes initialization |
|---|---|---|
| Value is known immediately and should not change | val name = "NoName" | The value is assigned at declaration and cannot be reassigned. |
| Value is known immediately but may change | var count = 0 | The variable starts with a valid value and can be updated later. |
| Value may be absent | var name: String? = null | The variable is initialized with null, and later access must handle null safety. |
| Class property is supplied by constructor | class User(val name: String) | The property is initialized when the object is created. |
| Mutable non-null property is assigned after object creation | lateinit var title: String | The property can be assigned later, but it must be assigned before use. |
Kotlin definite assignment with if, when, try, and loop branches
Kotlin must be able to prove that a variable is assigned on every path before it is read. Assigning it in only one branch is not enough.
fun main() {
val score = 75
val grade: String
if (score >= 50) {
grade = "Pass"
}
// Error: Variable 'grade' must be initialized
println(grade)
}
Assign the variable in every branch, or use the if expression directly.
fun main() {
val score = 75
val grade = if (score >= 50) {
"Pass"
} else {
"Fail"
}
println(grade)
}
Initialize Kotlin class properties in the constructor or init block
For class properties, Kotlin requires a non-null property to be initialized when the object is created, unless the property is abstract, delegated, nullable with a value such as null, or marked with lateinit where allowed.
class Report(title: String) {
val displayTitle: String
init {
displayTitle = title.trim()
}
}
If the property is simply copied from the constructor parameter, declare it directly in the primary constructor.
class Report(val displayTitle: String)
Use nullable variables when the Kotlin value can really be missing
Sometimes the correct initial value is no value. In that case, make the type nullable and handle the null case before using the value.
fun main() {
var selectedUser: User? = null
selectedUser = User("Suresh", 25)
println(selectedUser?.name ?: "No user selected")
}
data class User(val name: String, val age: Int)
Do not use a nullable type only to silence the compiler. Use it when null is a meaningful state in your program.
Use lateinit only for mutable non-null Kotlin properties assigned later
lateinit is useful when a non-null property cannot be assigned in the constructor but will be assigned before use, such as in some framework-managed classes. It works with var properties, not local variables, not val, and not primitive types such as Int or Boolean.
class UserRepository {
lateinit var defaultUser: User
fun load() {
defaultUser = User("Suresh", 25)
}
fun printDefaultUser() {
if (::defaultUser.isInitialized) {
println(defaultUser)
} else {
println("Default user is not loaded")
}
}
}
data class User(val name: String, val age: Int)
If you read a lateinit property before assigning it, the code compiles but fails at runtime with an UninitializedPropertyAccessException. For values that can safely start empty, prefer normal initialization such as emptyList(), mutableListOf(), 0, or an empty string.
Kotlin variable initialization syntax patterns
The following patterns show common ways to initialize variables correctly.
val name: String = "NoName" // immutable variable with explicit type
val city = "Hyderabad" // immutable variable with inferred type
var count: Int = 0 // mutable variable with initial value
var email: String? = null // nullable variable initialized with null
val users = mutableListOf<User>() // empty mutable list with type information
Checklist to fix Variable must be initialized in Kotlin code review
- Check the exact line where the variable is first read, not only the line where it is declared.
- Confirm that every
if,when,try, and loop path assigns the variable before use. - Prefer
valwhen the value is assigned once, because it makes initialization and reassignment rules clearer. - Use nullable types only when
nullis a valid program state and handle it with safe calls, Elvis operator, or explicit checks. - Use
lateinitonly for class-level mutable properties that are guaranteed to be assigned before access. - Initialize collections with
listOf(),mutableListOf(),arrayListOf(), orArrayList<Type>()instead of declaring an empty reference.
FAQs on Kotlin Variable must be initialized error
How do you initialize a variable in Kotlin?
You initialize a Kotlin variable by assigning a value before the variable is used. For example, write val name = "NoName", var count = 0, or val users = mutableListOf<User>(). If the value may be absent, use a nullable type such as var name: String? = null and handle null safely.
Why does Kotlin require local variables to be initialized before use?
Kotlin uses definite assignment checks. The compiler rejects code where a local variable may be read before receiving a value. This prevents accidental reads from an undefined value and keeps non-null types reliable.
How do I check if a lateinit variable is initialized in Kotlin?
For a lateinit var property, use the property reference check ::propertyName.isInitialized from a place where that property reference is accessible. This check is for lateinit properties only; it is not used for normal local variables.
Should I use null or lateinit to fix Variable must be initialized?
Use null only when missing data is a valid state and the rest of the code handles that state. Use lateinit only for mutable non-null properties that are assigned after object creation. For most local variables and collections, the better fix is to assign an actual initial value.
Can a val variable be declared first and initialized later in Kotlin?
Yes, a local val can be declared first and assigned exactly once later, but Kotlin must be able to prove that the assignment happens before the value is read. If assignment happens only in some branches, the compiler reports that the variable must be initialized.
Kotlin Variable must be initialized error summary
In this Kotlin tutorial we have handled “Error Variable must be initialized” by initializing the variable.
The practical rule is: declare the type only when needed, but always assign a value before the first read. Use constructor initialization for class properties, branch-safe assignment for conditional logic, nullable types for genuinely optional values, and lateinit only when delayed assignment is part of the design.
TutorialKart.com