Lateinit Usage

ID

kotlin.lateinit_usage

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Kotlin

Tags

best-practice, reliability

Description

Flags property declarations that carry the lateinit modifier. lateinit opts a property out of Kotlin’s null-safety system: the type stays non-nullable but the compiler no longer enforces that a value has been assigned before the first read.

Rationale

class Service {
    lateinit var client: Client
}

Reading client before the application has assigned a value throws UninitializedPropertyAccessException at runtime. The construct defers what the type system normally catches at compile time to an unspecified later moment, producing crashes that depend on initialisation order, threading, or framework lifecycles.

Common causes of lateinit failures include constructor-injection frameworks that did not actually inject the property, test setup methods that skipped a step, and Android lifecycle callbacks that fire before onCreate. None of these are surfaced by the type — every read is a leap of faith.

Remediation

class Service {
    // Compute on first access; thread-safe.
    val client: Client by lazy { buildClient() }
}

class Service {
    // Keep the value in the type system; force callers to handle the null case.
    var client: Client? = null
}
  • by lazy { …​ } initialises on first read and removes the failure mode entirely.

  • A nullable property with an explicit null initial value documents the "may not be ready yet" state in the type, so the compiler forces callers to handle it.