Mr.AndroidShin / Dev Tools

Debugging log · Kotlin

"Inferred type is String? but String was expected"

Kotlin stopped my build over a value I was sure held text: inferred type is String? but String was expected. The frustrating first reaction is "but it clearly has a value" — and that's exactly the point Kotlin is making. It doesn't care what the value happens to be at runtime; it cares that the type allows null, and you're using it somewhere null isn't permitted.

The short version: the trailing ? means "might be null". You're passing a String? where a non-null String is required. Fix it by proving it's not null (a check, ?:, or let) rather than forcing it with !!.

What the ? actually means

In Kotlin, String and String? are different types. String can never be null; String? might be. This is the whole point of Kotlin's null safety: the compiler tracks nullability in the type system so a NullPointerException becomes a compile error instead of a crash. The message isn't a bug in your code — it's the safety net catching a place where a possibly-null value would flow into code that can't handle null.

Where the ? sneaks in

Fix 1 — the Elvis operator (a sensible default)

Provide a fallback for the null case with ?::

val name: String = maybeName ?: "Unknown"

Now the result is a non-null String: the real value if present, the fallback if null. This is usually the cleanest fix when a reasonable default exists.

Fix 2 — check, then use

If you only want to act when the value is present, a null check narrows the type inside the block:

val n = maybeName
if (n != null) {
    // n is smart-cast to non-null String here
    greet(n)
}
// or scope it with let:
maybeName?.let { greet(it) }

Kotlin's smart casts mean that after you've checked for null, it treats the value as non-null within that scope — no extra syntax needed.

Fix 3 — fix the source's nullability

Sometimes the right fix is upstream. If a property never should be null, declare it non-null (val name: String) and initialize it properly, rather than declaring it nullable and fighting the ? at every use. Making the type honest removes the error everywhere at once.

Resist !!. The double-bang asserts "this is never null, trust me" and turns the compile error back into a runtime crash the moment you're wrong. It's occasionally justified, but reaching for it to silence this message trades a safe compile-time signal for an unsafe runtime one. Prefer ?:, a check, or fixing the type.

Quick decision guide

Variable and value names above are illustrative — apply the pattern to your own code.