{"record":{"id":"381e6a966c2e7c5e","repo":"apache/beam","slug":"expected-to-find-a-single-mapping-constructor-but-found","errorCode":null,"errorMessage":"Expected to find a single mapping constructor but found ${mappingConstructors.size()}","messagePattern":"Expected to find a single mapping constructor but found (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":420,"sourceCode":"    return (Object[]) valueTypeArray;\n  }\n\n  private Constructor<PTransform<InputT, OutputT>> findMappingConstructor(\n      Constructor<?>[] constructors, JavaClassLookupPayload payload) {\n    Row constructorRow = decodeRow(payload.getConstructorSchema(), payload.getConstructorPayload());\n\n    List<Constructor<?>> mappingConstructors =\n        Arrays.stream(constructors)\n            .filter(c -> c.getParameterCount() == payload.getConstructorSchema().getFieldsCount())\n            .filter(c -> parametersCompatible(c.getParameters(), constructorRow))\n            .collect(Collectors.toList());\n\n    if (mappingConstructors.size() == 0) {\n      throw new RuntimeException(\n          \"Could not find a matching constructor. When using field names, make sure they are \"\n              + \"available in the compiled Java class.\");\n    } else if (mappingConstructors.size() != 1) {\n      throw new RuntimeException(\n          \"Expected to find a single mapping constructor but found \" + mappingConstructors.size());\n    }\n    return (Constructor<PTransform<InputT, OutputT>>) mappingConstructors.get(0);\n  }\n\n  private boolean isConstructorMethodForName(\n      Method method, String nameFromPayload, AllowedClass allowListClass) {\n    for (Annotation annotation : method.getAnnotations()) {\n      if (annotation instanceof MultiLanguageConstructorMethod) {\n        if (nameFromPayload.equals(((MultiLanguageConstructorMethod) annotation).name())) {\n          if (allowListClass.isAllowedConstructorMethod(nameFromPayload)) {\n            return true;\n          } else {\n            throw new RuntimeException(\n                \"Constructor method \" + nameFromPayload + \" needs to be explicitly allowed\");\n          }\n        }\n      }","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L402-L438","documentation":"findMappingConstructor found more than one constructor matching the field count and parameter compatibility. The provider requires exactly one unambiguous mapping constructor and throws RuntimeException with the number found.","triggerScenarios":"A class has overloaded constructors with the same arity and all parameters compatible with the Row (e.g. (int, String) and (long, String), or two same-arity constructors with compatible primitive widening).","commonSituations":"Classes with convenience overloads; adding a new constructor after the payload schema was generated; autoboxing making several constructors appear compatible.","solutions":["Remove or consolidate overloaded constructors so exactly one matches the schema arity/types.","Make parameter types stricter (avoid int/long overloads) so parametersCompatible yields a single match.","Use a named constructor method (MultiLanguageConstructorMethod) instead of ambiguous constructors.","Catch RuntimeException and log candidate constructors for diagnosis."],"exampleFix":"// before\npublic T(int a, String b) {...}\npublic T(long a, String b) {...}\n// after\npublic T(long a, String b) {...}","handlingStrategy":"try-catch","validationCode":"long matches = Arrays.stream(Target.class.getConstructors()).filter(c -> c.getParameterCount() == schema.getFieldsCount()).count(); if (matches != 1) throw new IllegalStateException(\"Expected 1 matching constructor, found \" + matches);","typeGuard":null,"tryCatchPattern":"try { constructor(payload); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Expected to find a single mapping constructor\")) { /* remove ambiguity or use a named method */ } throw e; }","preventionTips":["Avoid same-arity constructor overloads in transform classes","Prefer factory/constructor methods with unique names","Avoid int/long overload pairs that widen compatibly","Count matching constructors in a startup self-check"],"tags":["java","reflection","ambiguity","constructor-overload"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}