apple/pkl · error · ConversionException
Error invoking constructor of class `%s`.
Error message
Error invoking constructor of class `%s`.
What it means
PMapToMap maps a Pkl Map value to a Java Map implementation chosen by the requested target type. It instantiates the target map class via reflection, preferring a (int capacity, float loadFactor) constructor and passing (length/0.75f)+1 and 0.75f. This ConversionException wraps any Throwable thrown while invoking that two-argument constructor, such as an IllegalArgumentException from a constructor that rejects those arguments or an InvocationTargetException from constructor logic.
Source
Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/PMapToMap.java:65
var typeArguments = mapType.getActualTypeArguments();
var keyType = Reflection.normalize(typeArguments[0]);
var valueType = Reflection.normalize(typeArguments[1]);
return createInstantiator(targetClass)
.map(instantiator -> new ConverterImpl<>(instantiator, keyType, valueType));
}
private <K, V> Optional<Function<Integer, Map<K, V>>> createInstantiator(Class<?> clazz) {
try {
// constructor with capacity and load factor arguments
var ctor2 =
lookup.findConstructor(clazz, MethodType.methodType(void.class, int.class, float.class));
return Optional.of(
length -> {
try {
//noinspection unchecked
return (Map<K, V>) ctor2.invoke((int) (length / .75f) + 1, .75f);
} catch (Throwable t) {
throw new ConversionException(
String.format("Error invoking constructor of class `%s`.", clazz), t);
}
});
} catch (NoSuchMethodException e2) {
try {
// default constructor
var ctor0 = lookup.findConstructor(clazz, MethodType.methodType(void.class));
return Optional.of(
length -> {
try {
//noinspection unchecked
return (Map<K, V>) ctor0.invoke();
} catch (Throwable t) {
throw new ConversionException(
String.format("Error invoking constructor of class `%s`.", clazz), t);
}
});
} catch (NoSuchMethodException e0) {View on GitHub (pinned to f3efcbfc9b)
Solutions
- Check the cause (`e.getCause()`) to see why the (int,float) constructor threw; fix the custom map class so its (int, float) constructor accepts initialCapacity and loadFactor semantics.
- Add a no-arg constructor to your Map class so PMapToMap falls back to `createInstantiator`'s default-constructor path instead of the (int,float) constructor.
- Map to a standard map type (java.util.HashMap, LinkedHashMap, TreeMap, SortedMap) whose (int,float) constructor is well-behaved.
- If the constructor throws only for large inputs, reduce the size of the Pkl map or raise the limit inside the constructor.
Example fix
// before
class Sizes extends HashMap<String, Integer> {
Sizes(int maxEntries, float unused) { super(maxEntries); if (maxEntries > 1000) throw new IllegalArgumentException("too big"); }
}
// after
class Sizes extends HashMap<String, Integer> {
Sizes(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); } // accept JDK semantics
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before conversion, verify the target map class has a well-behaved (int, float) constructor:
static boolean hasSafeCapacityCtor(Class<?> c) {
try {
var ctor = c.getConstructor(int.class, float.class);
var inst = ctor.newInstance(4, 0.75f); // smoke-test invocation
inst.getClass().cast(inst);
return true;
} catch (ReflectiveOperationException | RuntimeException e) {
return false;
}
} Type guard
static boolean isStandardMap(Class<?> c) {
return java.util.HashMap.class.isAssignableFrom(c)
|| java.util.LinkedHashMap.class.isAssignableFrom(c)
|| java.util.TreeMap.class.isAssignableFrom(c);
} Try / catch
try {
Map<String, Object> result = valueRenderer.render(pValue, my.CustomMap.class);
} catch (ConversionException e) {
Throwable cause = e.getCause();
log.error("Constructor of " + cause + " failed; falling back to HashMap", e);
Map<String, Object> result = new java.util.LinkedHashMap<>(); // fallback
} Prevention
- Give custom Map classes standard JDK constructor semantics: (int initialCapacity, float loadFactor) and a no-arg constructor that never throw.
- Prefer standard JDK map types (HashMap, LinkedHashMap, SortedMap) as conversion targets.
- Smoke-test reflective instantiation of custom target classes in unit tests before production use.
When it happens
Trigger: Requesting a mapping to a Map subtype whose (int, float) constructor exists but fails when invoked during conversion, e.g. `ValueRenderer.render(config, my.CustomMap.class)` or DataFleet/Config conversions where CustomMap's (int,float) constructor validates its arguments or throws internally.
Common situations: Custom Map implementations whose capacity/load-factor constructor has different semantics (e.g. expects maxCapacity, not initialCapacity, and throws IllegalArgumentException for large sizes); constructors that throw on negative or oversized capacity for huge Pkl maps; constructors with side-effectful initialization that fails.
Related errors
- Error accessing constructor of class `%s`.
- Error invoking constructor `%s`.
- JavaType token must be parameterized.
- Error invoking constructor of class `%s`.
- Error accessing constructor of class `%s`.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/52124cc43a782215.
Report an issue: GitHub.