{"record":{"id":"c12a36a2190cb076","repo":"apple/pkl","slug":"implementationtype-must-be-assignable-to-reques","errorCode":null,"errorMessage":"`implementationType` must be assignable to `requestedType`, but `%s` is not assignable to `%s`.","messagePattern":"`implementationType` must be assignable to `requestedType`, but `(.+?)` is not assignable to `(.+?)`\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pkl-config-java/src/main/java/org/pkl/config/java/mapper/TypeMapping.java","lineNumber":42,"sourceCode":" * typical example is mapping {@link java.util.List} to {@link java.util.ArrayList}.\n */\n// kept simple for now\n// if we wanted to have more sophisticated mappings, we could:\n// * support mapping factories/strategies (cf. ConverterFactory/Converter)\n// * support parameterized mappings (e.g. Set<MyEnum> -> EnumSet<MyEnum>)\npublic final class TypeMapping<S, T extends S> {\n  public final Class<S> requestedType;\n  public final Class<T> implementationType;\n\n  private TypeMapping(Class<S> requestedType, Class<T> implementationType) {\n    if (Modifier.isAbstract(implementationType.getModifiers())) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"`implementationType` must not be abstract, but `%s` is.\",\n              implementationType.getTypeName()));\n    }\n    if (!requestedType.isAssignableFrom(implementationType)) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"`implementationType` must be assignable to `requestedType`, but `%s` is not assignable to `%s`.\",\n              implementationType.getTypeName(), requestedType.getTypeName()));\n    }\n    if (requestedType.isArray() || implementationType.isArray()) {\n      throw new IllegalArgumentException(\"Type mappings are not supported for array types.\");\n    }\n    this.requestedType = requestedType;\n    this.implementationType = implementationType;\n  }\n\n  public static <S, T extends S> TypeMapping<S, T> of(\n      Class<S> requestedType, Class<T> implementationType) {\n    return new TypeMapping<>(requestedType, implementationType);\n  }\n\n  @Override\n  public boolean equals(@Nullable Object obj) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-config-java/src/main/java/org/pkl/config/java/mapper/TypeMapping.java#L24-L60","documentation":"The TypeMapping constructor verifies with requestedType.isAssignableFrom(implementationType) that the implementation class actually implements/extends the requested type. A mapping between unrelated types would produce ClassCastException later, so it is rejected up front.","triggerScenarios":"TypeMapping.of(S.class, T.class) where S is not a supertype of T, e.g. TypeMapping.of(String.class, Integer.class).","commonSituations":"Typos in generics erased by raw Class arguments; swapping the two arguments; refactoring a class hierarchy so the old implementation no longer extends the requested type.","solutions":["Ensure the implementation type genuinely extends/implements the requested type.","Swap the arguments if you inverted requestedType and implementationType.","Add a compile-time bound (TypeMapping.of(S.class, T.class) with T extends S) so the compiler catches it."],"exampleFix":"// before\nTypeMapping.of(List.class, String.class);\n// after\nTypeMapping.of(List.class, ArrayList.class);","handlingStrategy":"validation","validationCode":"if (!requested.isAssignableFrom(impl)) throw new IllegalArgumentException(impl + \" is not a \" + requested);","typeGuard":"static <S, T extends S> boolean assignable(Class<S> s, Class<T> t) { return s.isAssignableFrom(t); }","tryCatchPattern":"try { TypeMapping.of(req, impl); } catch (IllegalArgumentException e) { /* fix hierarchy or swap args */ }","preventionTips":["Use the statically-typed of() signature so javac enforces T extends S","Double-check argument order: requested type first, implementation second"],"tags":["java","type-mapping","assignability","illegal-argument"],"backgroundTag":"type-mismatch","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}