quarkusio/quarkus · error · RuntimeException
Could not find parameters for constructor ${nonDefaultConstr
Error message
Could not find parameters for constructor ${nonDefaultConstructorHolder.constructor} could not read field values ${constructorParamNameMap.keySet()} What it means
For an object with a non-default constructor, the recorder maps each constructor parameter to a field/property value read from the instance. After reading all matching fields, any constructor parameters that were never matched remain in constructorParamNameMap, meaning the object cannot be reconstructed faithfully — so recording fails.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java:1548
FieldDescriptor.of(param.getClass(), field.getName(), field.getType()),
context.loadDeferred(out),
context.loadDeferred(val));
}
@Override
public void prepare(MethodContext context) {
val.prepare(context);
}
});
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
if (!constructorParamNameMap.isEmpty()) {
throw new RuntimeException("Could not find parameters for constructor " + nonDefaultConstructorHolder.constructor
+ " could not read field values " + constructorParamNameMap.keySet());
}
NonDefaultConstructorHolder finalNonDefaultConstructorHolder = nonDefaultConstructorHolder;
DeferredParameter[] finalCtorHandles = nonDefaultConstructorHandles;
//create a deferred value to represent the object itself. This allows the creation to be split
//over multiple methods, which is important if this is a large object
DeferredArrayStoreParameter objectValue = new DeferredArrayStoreParameter(param, expectedType) {
@Override
ResultHandle createValue(MethodContext context, MethodCreator method, ResultHandle array) {
ResultHandle out;
//do the creation
if (finalNonDefaultConstructorHolder != null) {
out = method.newInstance(
ofConstructor(finalNonDefaultConstructorHolder.constructor.getDeclaringClass(),
finalNonDefaultConstructorHolder.constructor.getParameterTypes()),
Arrays.stream(finalCtorHandles).map(m -> context.loadDeferred(m))
.toArray(ResultHandle[]::new));View on GitHub (pinned to e1c734241f)
Solutions
- Rename fields (or constructor params) so each constructor parameter matches a field name exactly
- Compile with -parameters so parameter names are available
- Register an explicit paramGenerator for the constructor so field matching is unnecessary
Example fix
// before
public Pool(int max) { this.size = max; } // 'max' has no matching field
// after
public Pool(int max) { this.max = max; } // field 'max' exists Defensive patterns
Strategy: validation
Validate before calling
for (Parameter p : ctor.getParameters()) {
if (!hasFieldOrProperty(clazz, p.getName())) {
throw new IllegalStateException("Constructor param '" + p.getName()
+ "' of " + clazz + " has no matching field/property");
}
} Type guard
boolean ctorParamsMapToFields(Constructor<?> c) {
Set<String> fields = new HashSet<>();
for (Class<?> k = c.getDeclaringClass(); k != null; k = k.getSuperclass())
Arrays.stream(k.getDeclaredFields()).forEach(f -> fields.add(f.getName()));
return Arrays.stream(c.getParameters()).allMatch(p -> fields.contains(p.getName()));
} Try / catch
try {
recorder.record(value);
} catch (RuntimeException e) {
if (String.valueOf(e.getMessage()).startsWith("Could not find parameters for constructor")) {
throw new IllegalStateException("Align constructor param names with fields on " + value.getClass(), e);
}
throw e;
} Prevention
- Name constructor parameters identically to the fields they initialize
- Compile with -parameters so names are visible to the recorder
- Provide an explicit paramGenerator when naming conventions can't hold
When it happens
Trigger: Recording a class whose constructor parameter names don't correspond to any instance field/getter (e.g. parameter named 'capacity' but field is 'size'); missing -parameters compilation info for some parameters; subclass hiding a field.
Common situations: Classes where constructor parameter names differ from field names (no canonical naming); classes compiled without -parameters; renamed fields without updating constructor usage.
Related errors
- Unable to serialize ${param} as the wrong number of paramete
- Unable to determine the recordable constructor to use for ${
- Unable to serialize objects of type ${param.getClass()} to b
- Couldn't extract all parameters information for constructor
- Cannot serialise field '${i.getName()}' on object '${param}'
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4b43f0cc98ad77d8.
Report an issue: GitHub.