apple/pkl · error · IllegalArgumentException

Cannot parameterize `%s` because it does not have any type p

Error message

Cannot parameterize `%s` because it does not have any type parameters.

What it means

Types.parameterizedType() builds a ParameterizedType from a raw class plus type arguments. If the raw class declares zero type parameters there is nothing to parameterize, so it throws instead of silently ignoring the arguments.

Source

Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/Types.java:35

import io.leangen.geantyref.TypeArgumentNotInBoundException;
import io.leangen.geantyref.TypeFactory;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import org.pkl.core.Pair;

/**
 * A factory for parameterized type literals such as {@code List<String>} or {@code MyClass<Foo,
 * Bar>}. Used to express the desired target type in {@link ValueMapper#map(Object, Type)}.
 */
public final class Types {
  private Types() {}

  public static ParameterizedType parameterizedType(Class<?> rawType, Type... typeArguments) {
    var typeParamsCount = rawType.getTypeParameters().length;
    if (typeParamsCount == 0) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot parameterize `%s` because it does not have any type parameters.",
              rawType.getTypeName()));
    }
    if (typeArguments.length != typeParamsCount) {
      throw new IllegalArgumentException(
          String.format(
              "Expected %d type arguments for `%s`, but got %d.",
              typeParamsCount, rawType.getTypeName(), typeArguments.length));
    }
    for (Type arg : typeArguments) {
      if (arg instanceof Class<?> clazz) {
        if (clazz.isPrimitive()) {
          throw new IllegalArgumentException(
              String.format(
                  "`%s.class` is not a valid type argument. Did you mean `%s.class`?",
                  clazz, Reflection.toWrapperType(clazz).getSimpleName()));
        }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Use the raw class directly instead of parameterizing it.
  2. Pass a generic class (e.g. List.class, Optional.class) if you meant a parameterized type.
  3. Check rawType.getTypeParameters().length > 0 before calling.

Example fix

// before
Types.parameterizedType(String.class, Integer.class);
// after
Types.parameterizedType(List.class, String.class);
Defensive patterns

Strategy: validation

Validate before calling

if (rawType.getTypeParameters().length == 0) throw new IllegalArgumentException(rawType + " has no type parameters");

Type guard

static boolean isGeneric(Class<?> c) { return c.getTypeParameters().length > 0; }

Try / catch

try { Types.parameterizedType(raw, args); } catch (IllegalArgumentException e) { /* use raw class directly */ }

Prevention

When it happens

Trigger: parameterizedType(String.class, ...) or any call with a non-generic class; also via helpers like Types.listOf/pairOf only if given a raw class without parameters.

Common situations: Passing String.class or Integer.class where List.class/Map.class was intended; wrapping a non-generic custom class that was expected to be generic.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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