apple/pkl · error · KotlinCodeGeneratorException

Pkl function types are not supported by the Kotlin code…

Error message

Pkl function types are not supported by the Kotlin code generator.

What it means

KotlinCodeGenerator.toKotlinPoetName throws when a type alias resolves to a Pkl function type: KotlinPoet output for generated classes cannot represent Pkl function types, so the generator aborts instead of producing invalid Kotlin.

Solutions

  1. Replace the function type in the Pkl schema with a class or typealias that maps to a Kotlin type.
  2. Exclude the offending property/type from code generation.

Example fix

// before (Pkl)
transform: (String) -> Int
// after
transformer: Transformer // a class/interface
Defensive patterns

Strategy: validation

Validate before calling

fun containsFunctionType(t: PType?): Boolean =
  t is PType.Function // extend to walk property types of module schema before codegen

Type guard

fun isFunctionType(t: PType?): Boolean = t is PType.Function

Try / catch

try {
  generator.generate(module)
} catch (e: KotlinCodeGeneratorException) {
  if (e.message?.contains("function types are not supported") == true) {
    logger.error("Remove function-typed properties: ${e.message}")
  } else throw e
}

Prevention

When it happens

Trigger: A generated module declares a property or type alias whose type is a function type, e.g. `transform: (String) -> Int`.

Common situations: Modeling callbacks or lambdas in Pkl schemas, then generating Kotlin data classes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/acb6a5d551887b9a. Report an issue: GitHub.

Appendix: source

Thrown at pkl-codegen-kotlin/src/main/kotlin/org/pkl/codegen/kotlin/KotlinCodeGenerator.kt:751

          "pkl.base#DurationUnit" -> DURATION_UNIT
          "pkl.base#DataSizeUnit" -> DATA_SIZE_UNIT
          "pkl.base#Uri" -> URI
          else -> {
            val className = typeAlias.toKotlinPoetName()
            when {
              typeAlias.typeParameters.isEmpty() -> className
              typeArguments.isEmpty() -> {
                // no type arguments provided for a type alias with type parameters -> fill in
                // `Any?` (equivalent of `unknown`)
                val typeArgs = Array(typeAlias.typeParameters.size) { ANY_NULL }
                className.parameterizedBy(*typeArgs)
              }
              else -> className.parameterizedBy(*typeArguments.toKotlinPoet())
            }
          }
        }
      is PType.Function ->
        throw KotlinCodeGeneratorException(
          "Pkl function types are not supported by the Kotlin code generator."
        )
      is PType.Union ->
        if (CodeGeneratorUtils.isRepresentableAsString(this)) STRING
        else
          throw KotlinCodeGeneratorException(
            "Pkl union types are not supported by the Kotlin code generator."
          )

      // occurs on RHS of generic type aliases
      is PType.TypeVariable -> TypeVariableName(typeParameter.name)
      else -> throw AssertionError("Encountered unexpected PType subclass: $this")
    }

  private fun List<PType>.toKotlinPoet(): Array<TypeName> =
    map { it.toKotlinPoetName() }.toTypedArray()

  private val nameMapper = NameMapper(options.renames)

View on GitHub (pinned to f3efcbfc9b)