Skip to content

/errors/kotlin/only-safe-or-non-null-asserted-calls-allowed

Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

The commands on this page have not been executed by our verification runner yet.updated
tool
Kotlin
exit code
1
versions
Kotlin 1.x, Kotlin 2.x (K2 compiler)
os
any

Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String? is a Kotlin compile error: you called a member with . on a value whose type ends in ?, so it can be null. Kotlin forces you to handle that case. Use ?. to get null back, add a default with ?:, or check if (x != null) first so the compiler smart-casts the value to its non-null type. The K2 compiler (Kotlin 2.0+) prints the type in quotes: ... of type 'String?'.

Example

kotlin
fun main() {
    val name: String? = System.getenv("USER_NAME")
    println(name.length)          // error: name may be null
}

Fixes

kotlin
val name: String? = System.getenv("USER_NAME")

println(name?.length)             // Int?: null when name is null
println(name?.length ?: 0)        // Int: 0 when name is null

if (name != null) {
    println(name.length)          // smart cast to String inside the check
}

val len = name?.let { it.trim().length } ?: 0   // run a block only when non-null

println(name!!.length)            // throws NullPointerException if null: avoid

Smart cast on properties

A null check does not smart-cast a mutable property (var), or a property with a custom getter or from another module, because its value could change after the check. Copy it into a local val:

kotlin
class Form { var email: String? = null }

fun send(form: Form) {
    val email = form.email ?: return   // local val: smart cast works from here
    println(email.lowercase())
}

Operators

OperatorResult when the receiver is null
a?.bnull (no call happens)
a ?: defaultdefault
a!!.bThrows NullPointerException
a?.let { ... }The block is skipped and the result is null

Sources