apple/pkl · error · ConversionException
Expected a non-null value but got `null`. To allow null…
Error message
Expected a non-null value but got `null`. To allow null values, convert to a nullable Kotlin type, for example `String?`.
What it means
Config.to<T>() converts a Pkl Config value into a Kotlin type T. This error means the Pkl value is null but the requested Kotlin type T is non-nullable, so the conversion cannot proceed. The library deliberately tells you the fix: make T nullable (e.g. String?) to accept null.
Solutions
- Make the target Kotlin type nullable: config.to<String?>() instead of config.to<String>().
- If the field should never be null, fix the Pkl config/amendment so the property has a value.
- Provide a default before conversion: config["prop"]?.let { it.to<String>() } ?: fallback (check null on the Config view first).
Example fix
// before val name: String = config.to<String>() // after val name: String? = config.to<String?>()
Defensive patterns
Strategy: type-guard
Validate before calling
if (config["name"] == null) error("config.name is null; provide a value or use String?") Type guard
inline fun <reified T> Config.toOrNull(): T? = if (null is T) asNullable(typeOf<T>().javaType) else `as`(typeOf<T>().javaType)
Try / catch
val name = try {
config.to<String>()
} catch (e: ConversionException) {
null // or default value
} Prevention
- Use nullable Kotlin types (String?) for Pkl properties declared nullable.
- Give Pkl properties non-null defaults so nulls only appear when intentional.
- Run `pkl eval` validation on config files before loading them in Kotlin.
- Grep your Pkl schemas for `?` typed properties and mirror nullability in Kotlin call sites.
When it happens
Trigger: Calling config.to<String>() (or to<Foo>()) where the underlying Pkl property's value is null (e.g. `foo: String?` in Pkl set to null, or an амended property nulling it).
Common situations: Pkl schema allows a nullable field that is left null; an amendment sets a field to null; caller assumes required fields and uses non-nullable Kotlin types.
Related errors
- Cannot convert pkl.base#Int `$value` to kotlin.UByte…
- Cannot convert pkl.base#Int `$value` to kotlin.UInt because…
- Cannot convert pkl.base#Int `$value` to kotlin.ULong…
- Cannot convert pkl.base#Int `$value` to kotlin.UShort…
- Cannot convert pkl.base#Int
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/d0aae23de233a602.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-config-kotlin/src/main/kotlin/org/pkl/config/kotlin/ConfigExtensions.kt:48
/**
* Converts this [Config] node to type [T] using the configured
* [org.pkl.config.java.mapper.ValueMapper].
*
* To allow `null` values, specify a nullable type, for example `to<String?>()`.
*
* Kotlin code should prefer this method over [Config.as] for the following reasons:
* * does not clash with Kotlin's `as` keyword
* * throws [ConversionException] if conversion to non-nullable type returns `null`
* * easier to use with parameterized types: `to<List<String>>()` vs.
* `as(JavaType.listOf(String::class.java))`
*/
inline fun <reified T> Config.to(): T {
if (null is T) {
return asNullable(typeOf<T>().javaType)
}
return `as`(typeOf<T>().javaType)
?: throw ConversionException(
"Expected a non-null value but got `null`. " +
"To allow null values, convert to a nullable Kotlin type, for example `String?`."
)
}
/**
* Configures this [ValueMapperBuilder] with conversions and converter factories for Kotlin types.
*/
fun ValueMapperBuilder.forKotlin(): ValueMapperBuilder =
addConversions(KotlinConversions.all).addConverterFactories(KotlinConverterFactories.all)
/**
* Configures this [ConfigEvaluatorBuilder] with conversions and converter factories for Kotlin
* types.
*/
fun ConfigEvaluatorBuilder.forKotlin(): ConfigEvaluatorBuilder =
setValueMapperBuilder(valueMapperBuilder.forKotlin())
View on GitHub (pinned to f3efcbfc9b)