apple/pkl · error · JavaCodeGeneratorException

Cannot generate Java enum class for Pkl type alias

Error message

Cannot generate Java enum class for Pkl type alias `${typeAlias.displayName}` because string literal type "$literal" cannot be converted to a valid enum constant name.

What it means

When a string-literal type alias is represented as a Java enum, each string literal must map to a valid enum constant name via CodeGeneratorUtils.toEnumConstantName. Literals that cannot be converted (e.g. empty or entirely invalid characters) abort enum generation for that type alias.

Solutions

  1. Change the offending string literal in the Pkl module to something convertible (letters/underscores).
  2. Avoid empty-string literals in the union; use a named value like "none".
  3. Check for literals that reduce to only symbols or digits after sanitization and rename them.
  4. Disable enum representation for that alias (represent it as String) if the literal must stay as-is.

Example fix

// before (Pkl)
type Status = "" | "active"
// after
type Status = "unknown" | "active"
Defensive patterns

Strategy: validation

Validate before calling

fun literalIsEnumSafe(l: String) = l.isNotEmpty() && CodeGeneratorUtils.toEnumConstantName(l) != null

Type guard

fun String.toEnumNameOrNull(): String? = takeIf { it.isNotEmpty() }?.let { CodeGeneratorUtils.toEnumConstantName(it) }

Try / catch

try { generate() } catch (e: JavaCodeGeneratorException) { if ("cannot be converted to a valid enum constant name" in e.message!!) adjustLiterals() else throw e }

Prevention

When it happens

Trigger: A type alias like `type Direction = "" | "up" | ...` where one literal produces null from toEnumConstantName — typically empty strings or literals consisting only of characters not usable in a Java identifier.

Common situations: Pkl modules using `""` as a sentinel value in string unions, literals made solely of digits or punctuation (e.g. `"-"`, `"123"`), or locale-specific strings with only symbols.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

    return generateClass()
  }

  private fun generateSerialVersionUIDField(): FieldSpec {
    return FieldSpec.builder(Long::class.java, "serialVersionUID", Modifier.PRIVATE)
      .addModifiers(Modifier.STATIC, Modifier.FINAL)
      .initializer("0L")
      .build()
  }

  private fun generateEnumTypeSpec(
    typeAlias: TypeAlias,
    stringLiterals: Set<String>,
  ): TypeSpec.Builder {
    val enumConstantToPklNames =
      stringLiterals
        .groupingBy { literal ->
          CodeGeneratorUtils.toEnumConstantName(literal)
            ?: throw JavaCodeGeneratorException(
              "Cannot generate Java enum class for Pkl type alias `${typeAlias.displayName}` " +
                "because string literal type \"$literal\" cannot be converted to a valid enum constant name."
            )
        }
        .reduce { enumConstantName, firstLiteral, secondLiteral ->
          throw JavaCodeGeneratorException(
            "Cannot generate Java enum class for Pkl type alias `${typeAlias.displayName}` " +
              "because string literal types \"$firstLiteral\" and \"$secondLiteral\" " +
              "would both be converted to enum constant name `$enumConstantName`."
          )
        }

    val builder =
      TypeSpec.enumBuilder(typeAlias.simpleName)
        .addModifiers(Modifier.PUBLIC)
        .addField(String::class.java, "value", Modifier.PRIVATE)
        .addMethod(
          MethodSpec.constructorBuilder()

View on GitHub (pinned to f3efcbfc9b)