apple/pkl · error · IllegalArgumentException

Type argument `%s` for type parameter `%s` is not within bou

Error message

Type argument `%s` for type parameter `%s` is not within bound `%s`.

What it means

After building the parameterized type via Jackson's TypeFactory, a TypeArgumentNotInBoundException indicates a type argument violates the bound declared on the type parameter (e.g. List<Number> for T extends Comparable). It is rethrown as an IllegalArgumentException naming the argument, parameter, and bound.

Source

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

      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()));
        }
      }
    }
    try {
      return (ParameterizedType) TypeFactory.parameterizedClass(rawType, typeArguments);
    } catch (TypeArgumentNotInBoundException e) {
      throw new IllegalArgumentException(
          String.format(
              "Type argument `%s` for type parameter `%s` is not within bound `%s`.",
              e.getArgument().getTypeName(),
              e.getParameter().getTypeName(),
              e.getBound().getTypeName()));
    }
  }

  public static ParameterizedType optionalOf(Type elementType) {
    return parameterizedType(Optional.class, elementType);
  }

  public static Type arrayOf(Type elementType) {
    return TypeFactory.arrayOf(elementType);
  }

  public static ParameterizedType pairOf(Type firstType, Type secondType) {
    return parameterizedType(Pair.class, firstType, secondType);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Pass a type argument that satisfies the declared bound shown in the message.
  2. Read the type parameter's declaration on the raw class to see the required bound.
  3. Loosen the bound on the generic class if the wider type is intended.

Example fix

// before
Types.parameterizedType(NumberBox.class, String.class); // T extends Number
// after
Types.parameterizedType(NumberBox.class, Integer.class);
Defensive patterns

Strategy: validation

Validate before calling

check each type argument satisfies the raw class's declared TypeVariable bounds before calling

Try / catch

try { Types.parameterizedType(raw, args); } catch (IllegalArgumentException e) { /* message names argument, parameter and bound */ }

Prevention

When it happens

Trigger: parameterizedType(SomeClass.class, arg.class) where arg does not satisfy SomeClass's declared type-parameter bound, e.g. Types.pairOf on a class declaring <T extends Number> with String.class.

Common situations: Using generic container classes with constrained type parameters; hierarchy refactors that tighten a bound while call sites still pass the old type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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