{"record":{"id":"ba2d4c9782d0a4e5","repo":"apache/beam","slug":"no-suitable-static-factory-method-s-s","errorCode":null,"errorMessage":"No suitable static factory method: %s.%s(...)","messagePattern":"No suitable static factory method: (.+?)\\.(.+?)\\(\\.\\.\\.\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java","lineNumber":246,"sourceCode":"  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static <FieldT extends TFieldIdEnum, T extends TBase<T, FieldT>>\n      Map<FieldT, FieldMetaData> thriftFieldDescriptors(Class<?> targetClass) {\n    return (Map<FieldT, FieldMetaData>) FieldMetaData.getStructMetaDataMap((Class<T>) targetClass);\n  }\n\n  private FieldValueTypeInformation fieldValueTypeInfo(Class<?> type, String fieldName) {\n    if (TUnion.class.isAssignableFrom(type)) {\n      final List<Method> factoryMethods =\n          Stream.of(type.getDeclaredMethods())\n              .filter(m -> m.getName().equals(fieldName))\n              .filter(m -> m.getModifiers() == (Modifier.PUBLIC | Modifier.STATIC))\n              .filter(m -> m.getParameterCount() == 1)\n              .filter(m -> m.getReturnType() == type)\n              .collect(Collectors.toList());\n      if (factoryMethods.isEmpty()) {\n        throw new IllegalArgumentException(\n            String.format(\n                \"No suitable static factory method: %s.%s(...)\", type.getName(), fieldName));\n      }\n      if (factoryMethods.size() > 1) {\n        throw new IllegalStateException(\"Overloaded factory methods: \" + factoryMethods);\n      }\n      return FieldValueTypeInformation.forSetter(\n          TypeDescriptor.of(type), factoryMethods.get(0), \"\");\n    } else {\n      try {\n        return FieldValueTypeInformation.forField(\n            TypeDescriptor.of(type), type.getDeclaredField(fieldName), 0);\n      } catch (NoSuchFieldException e) {\n        throw new IllegalArgumentException(e);\n      }\n    }\n  }\n","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java#L228-L264","documentation":"For thrift union case fields, ThriftSchema.fieldValueTypeInfo looks for a static single-argument factory method on the case type whose name matches the field, is public static, takes exactly one parameter, and returns the case type. If none exists, an IllegalArgumentException of this form is thrown.","triggerScenarios":"Building a schema for a TUnion subclass whose case field type lacks the expected static factory method (the generated fromFieldName-style method), usually because classes were generated with a different thrift compiler version or options.","commonSituations":"Regenerating unions with a thrift compiler that doesn't emit the factory methods; hand-written classes mimicking unions without the static factories; mixed thrift runtime/generator version mismatch.","solutions":["Regenerate the thrift classes with a thrift compiler version matching the beam-io-thrift expectations so union factory methods are emitted","Add a public static method named after the field that accepts one parameter and returns the union case type","Avoid hand-rolled TUnion subclasses; use thrift-compiler-generated ones"],"exampleFix":"// before\nclass MyUnion extends TUnion<...> { /* no static factory for field 'intValue' */ }\n// after\npublic static MyUnion intValue(Integer value) { return new MyUnion(MyUnion._Fields.INT_VALUE, value); }","handlingStrategy":"validation","validationCode":"boolean ok = java.util.Arrays.stream(MyUnion.class.getDeclaredMethods()).anyMatch(m -> java.lang.reflect.Modifier.isPublic(m.getModifiers()) && java.lang.reflect.Modifier.isStatic(m.getModifiers()) && m.getParameterCount() == 1);","typeGuard":null,"tryCatchPattern":"try { schema = ThriftSchema.provider().schemaFor(TypeDescriptor.of(MyUnion.class)); } catch (IllegalArgumentException e) { throw new IllegalStateException(\"Union case lacks static factory; regenerate thrift classes\", e); }","preventionTips":["Always use thrift-compiler-generated unions","Use the same thrift compiler version as the beam-io-thrift build expects","Add a unit test that infers schemas for every union type"],"tags":["java","thrift","union","reflection"],"backgroundTag":"method-not-implemented","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}