apple/pkl · error · KotlinCodeGeneratorException

Pkl union types are not supported by the Kotlin code…

Error message

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

What it means

Union types are only generated when all members are string literals (then emitted as String, via isRepresentableAsString). Any other union reaching toKotlinPoetName has no Kotlin representation and throws KotlinCodeGeneratorException.

Solutions

  1. Replace the union with string literals (`typealias X = "a"|"b"`) if it represents an enumeration.
  2. Model the union as a sealed-style set of classes or a single common supertype in Pkl.
  3. Loosen the property to one concrete type that codegen supports.

Example fix

// before (Pkl)
value: Int | String
// after
typealias Value = "one" | "two"
value: Value
Defensive patterns

Strategy: validation

Validate before calling

fun isUnionSafeForKotlin(t: PType?): Boolean =
  t !is PType.Union || CodeGeneratorUtils.isRepresentableAsString(t)

Type guard

fun isKotlinUnionSafe(t: PType?): Boolean =
  t !is PType.Union || CodeGeneratorUtils.isRepresentableAsString(t)

Try / catch

try {
  generator.generate(module)
} catch (e: KotlinCodeGeneratorException) {
  if (e.message?.contains("union types are not supported") == true) {
    logger.error("Replace non-string union with typealias or class: ${e.message}")
  } else throw e
}

Prevention

When it happens

Trigger: A property/alias typed with a non-string-literal union, e.g. `x: Int | String`, `y: A | B`, processed by Kotlin codegen.

Common situations: Schemas using unions for constrained numbers or mixed-type fallbacks (`String | Null` aside, typically heterogeneous unions), then generating Kotlin bindings.

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/d75314a53b7103c6. Report an issue: GitHub.

Appendix: source

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

              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)