apache/beam · error · IllegalStateException

Overloaded factory methods

Error message

Overloaded factory methods: %s

What it means

When more than one static factory method matches a thrift union case field (same name, public static, one parameter, returning the case type), ThriftSchema cannot disambiguate and throws an IllegalStateException listing the overloaded methods.

Solutions

  1. Remove or rename extra overloads so exactly one static factory method matches the field name
  2. Regenerate the union classes from the .thrift file to restore a single canonical factory per case
  3. Check the exception message listing the offending methods and keep only the generated one

Example fix

// before
public static MyUnion intValue(Integer v) {...}
public static MyUnion intValue(long v) {...}   // ambiguous overload
// after
public static MyUnion intValue(Integer v) {...}
Defensive patterns

Strategy: validation

Validate before calling

long count = java.util.Arrays.stream(MyUnion.class.getDeclaredMethods()).filter(m -> m.getName().equals("intValue") && m.getParameterCount() == 1).count(); if (count != 1) { throw new IllegalStateException("expected exactly one static factory for union case"); }

Try / catch

try { schema = ThriftSchema.provider().schemaFor(td); } catch (IllegalStateException e) { throw new IllegalStateException("Remove overloaded union factory methods", e); }

Prevention

When it happens

Trigger: A union case type declaring multiple overloads of the field-named static factory (e.g. differing parameter types), so the reflection filter matches more than one method.

Common situations: Hand-added convenience overloads in generated thrift union classes; thrift compiler changes producing extra factory signatures; subclassing generated unions and adding overloads.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/5a35fd688d5a654f. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java:251

    return (Map<FieldT, FieldMetaData>) FieldMetaData.getStructMetaDataMap((Class<T>) targetClass);
  }

  private FieldValueTypeInformation fieldValueTypeInfo(Class<?> type, String fieldName) {
    if (TUnion.class.isAssignableFrom(type)) {
      final List<Method> factoryMethods =
          Stream.of(type.getDeclaredMethods())
              .filter(m -> m.getName().equals(fieldName))
              .filter(m -> m.getModifiers() == (Modifier.PUBLIC | Modifier.STATIC))
              .filter(m -> m.getParameterCount() == 1)
              .filter(m -> m.getReturnType() == type)
              .collect(Collectors.toList());
      if (factoryMethods.isEmpty()) {
        throw new IllegalArgumentException(
            String.format(
                "No suitable static factory method: %s.%s(...)", type.getName(), fieldName));
      }
      if (factoryMethods.size() > 1) {
        throw new IllegalStateException("Overloaded factory methods: " + factoryMethods);
      }
      return FieldValueTypeInformation.forSetter(
          TypeDescriptor.of(type), factoryMethods.get(0), "");
    } else {
      try {
        return FieldValueTypeInformation.forField(
            TypeDescriptor.of(type), type.getDeclaredField(fieldName), 0);
      } catch (NoSuchFieldException e) {
        throw new IllegalArgumentException(e);
      }
    }
  }

  @Override
  public @NonNull SchemaUserTypeCreator schemaTypeCreator(
      @NonNull TypeDescriptor<?> targetTypeDescriptor, @NonNull Schema schema) {
    final Map<TFieldIdEnum, FieldMetaData> fieldDescriptors =
        schemaFieldDescriptors(targetTypeDescriptor.getRawType(), schema);

View on GitHub (pinned to 12126d8942)