apple/pkl · error · JavaCodeGeneratorException

Pkl ` ` types are not supported by the Java code generator.

Error message

Pkl `${this}` types are not supported by the Java code generator.

What it means

toJavaPoetName maps Pkl types to JavaPoet TypeNames; PType.MODULE and PType.THIS (self types) have no Java representation, so generation throws. Supporting self types would require recursive generics like `class Foo<T extends Foo<T>>`, which is not implemented (see TODO).

Solutions

  1. Refactor the Pkl module to avoid MODULE/THIS-typed properties; use a concrete class type instead.
  2. Replace `this`-typed declarations with the explicit class name.
  3. Split self-referential parts into a separate non-generated API surface.
  4. Request/await upstream support for self types (there is an explicit TODO).

Example fix

// before (Pkl)
prop: this
// after
prop: ModuleClass
Defensive patterns

Strategy: validation

Validate before calling

fun usesSelfType(module: Module): Boolean = module.properties.any { it.type in setOf(PType.MODULE, PType.THIS) }

Type guard

fun PType.isSelfType() = this == PType.MODULE || this == PType.THIS

Try / catch

try { generate() } catch (e: JavaCodeGeneratorException) { if ("types are not supported" in e.message!!) refactorSelfTypes() else throw e }

Prevention

When it happens

Trigger: Generating Java for a schema whose property/declared type is the module type or `this` — e.g. a property typed as the enclosing module name or literal `this` in a Pkl module.

Common situations: Modules with self-referential builder/fluent APIs, properties typed as the module itself, or `this`-typed function returns in Pkl definitions.

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

Appendix: source

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

    val baseName = toJavaPoetName(boxed = true)
    return if (this is PType.Class && (pClass.isAbstract || pClass.isOpen)) {
      WildcardTypeName.subtypeOf(baseName)
    } else {
      baseName
    }
  }

  private val PType.isBytesClass: Boolean
    get() = this is PType.Class && this.pClass.info == PClassInfo.Bytes

  private fun PType.toJavaPoetName(nullable: Boolean = false, boxed: Boolean = false): TypeName =
    when (this) {
      PType.UNKNOWN -> OBJECT.nullableIf(nullable)
      PType.NOTHING -> TypeName.VOID
      PType.MODULE,
      PType.THIS ->
        // TODO: support self types: `class Foo<T extends Foo<T>>`
        throw JavaCodeGeneratorException(
          "Pkl `${this}` types are not supported by the Java code generator."
        )
      is PType.StringLiteral -> STRING.nullableIf(nullable)
      is PType.Class -> {
        // if in doubt, spell it out
        when (val classInfo = pClass.info) {
          PClassInfo.Any -> OBJECT
          PClassInfo.Typed,
          PClassInfo.Dynamic -> OBJECT.nullableIf(nullable)
          PClassInfo.Boolean -> TypeName.BOOLEAN.boxIf(boxed).nullableIf(nullable)
          PClassInfo.String -> STRING.nullableIf(nullable)
          // seems more useful to generate `double` than `java.lang.Number`
          PClassInfo.Number -> TypeName.DOUBLE.boxIf(boxed).nullableIf(nullable)
          PClassInfo.Int -> TypeName.LONG.boxIf(boxed).nullableIf(nullable)
          PClassInfo.Float -> TypeName.DOUBLE.boxIf(boxed).nullableIf(nullable)
          PClassInfo.Duration -> DURATION.nullableIf(nullable)
          PClassInfo.DataSize -> DATA_SIZE.nullableIf(nullable)
          PClassInfo.Bytes -> ArrayTypeName.of(TypeName.BYTE)

View on GitHub (pinned to f3efcbfc9b)