apache/beam · error · RuntimeException
Could not find a matching constructor. When using field…
Error message
Could not find a matching constructor. When using field names, make sure they are available in the compiled Java class.
What it means
findMappingConstructor filters the target class's constructors by parameter count and by compatibility of each parameter with the constructor Row. If no constructor matches, it throws RuntimeException advising that field names must be present in the compiled class (schema-based field-name matching relies on reflection metadata).
Solutions
- Recompile the target class with -parameters so constructor parameter names are retained.
- Ensure the expansion service classpath contains the exact class version the payload schema was generated from.
- Check getFieldsCount and field types in the payload against the intended constructor signature.
- Catch RuntimeException and return a list of available constructors to help debug the mismatch.
Example fix
// before (build.gradle)
compileJava { }
// after
tasks.withType(JavaCompile) { options.compilerArgs << '-parameters' } Defensive patterns
Strategy: try-catch
Validate before calling
long matches = Arrays.stream(Target.class.getConstructors()).filter(c -> c.getParameterCount() == schema.getFieldsCount()).count(); if (matches == 0) throw new IllegalStateException("No constructor with arity " + schema.getFieldsCount()); Try / catch
try { constructor(payload); } catch (RuntimeException e) { if (e.getMessage().contains("Could not find a matching constructor")) { /* dump class constructors vs payload schema */ } throw e; } Prevention
- Compile with -parameters
- Keep payload schema generation in lockstep with class versions
- Pin the expansion service classpath to the transform jar version
- Log candidate constructors on failure
When it happens
Trigger: constructor(payload) is called with a constructorSchema whose field count or field types/names do not match any constructor of the loaded class — e.g. parameter names stripped by compilation without -parameters, or schema built for an older class version.
Common situations: Compiling without -parameters so name-based matching fails; class version mismatch between the expansion service classpath and the payload schema; overloaded constructors causing count mismatch.
Related errors
- Could not find a matching constructor method. When using…
- A method marked with SchemaCreate in class
- AutoValue builder class
- Can not call prepareRun
- Cannot create UDF from method: method
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f077248713ab567f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java:416
Object valueTypeArray = Array.newInstance(arrayComponentType, decodedValues.size());
for (int i = 0; i < decodedValues.size(); i++) {
Array.set(valueTypeArray, i, arrayComponentType.cast(decodedValues.get(i)));
}
return (Object[]) valueTypeArray;
}
private Constructor<PTransform<InputT, OutputT>> findMappingConstructor(
Constructor<?>[] constructors, JavaClassLookupPayload payload) {
Row constructorRow = decodeRow(payload.getConstructorSchema(), payload.getConstructorPayload());
List<Constructor<?>> mappingConstructors =
Arrays.stream(constructors)
.filter(c -> c.getParameterCount() == payload.getConstructorSchema().getFieldsCount())
.filter(c -> parametersCompatible(c.getParameters(), constructorRow))
.collect(Collectors.toList());
if (mappingConstructors.size() == 0) {
throw new RuntimeException(
"Could not find a matching constructor. When using field names, make sure they are "
+ "available in the compiled Java class.");
} else if (mappingConstructors.size() != 1) {
throw new RuntimeException(
"Expected to find a single mapping constructor but found " + mappingConstructors.size());
}
return (Constructor<PTransform<InputT, OutputT>>) mappingConstructors.get(0);
}
private boolean isConstructorMethodForName(
Method method, String nameFromPayload, AllowedClass allowListClass) {
for (Annotation annotation : method.getAnnotations()) {
if (annotation instanceof MultiLanguageConstructorMethod) {
if (nameFromPayload.equals(((MultiLanguageConstructorMethod) annotation).name())) {
if (allowListClass.isAllowedConstructorMethod(nameFromPayload)) {
return true;
} else {
throw new RuntimeException(View on GitHub (pinned to 12126d8942)