apache/beam · error · IllegalArgumentException

Class <descriptor> has final fields and no registered creato

Error message

Class <descriptor> has final fields and no registered creator. Cannot use as schema, as we don't know how to create this object automatically

What it means

JavaFieldSchema builds a schema by reflecting over a class's fields and constructs instances without a user-supplied creator. If any field is final, Beam cannot assign it reflectively without a registered creator method, so it rejects the class with an IllegalArgumentException.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/JavaFieldSchema.java:85

      for (int i = 0; i < fields.size(); ++i) {
        types.add(FieldValueTypeInformation.forField(typeDescriptor, fields.get(i), i));
      }
      types.sort(JavaBeanUtils.comparingNullFirst(FieldValueTypeInformation::getNumber));
      validateFieldNumbers(types);

      // If there are no creators registered, then make sure none of the schema fields are final,
      // as we (currently) have no way of creating classes in this case.
      if (ReflectUtils.getAnnotatedCreateMethod(typeDescriptor.getRawType()) == null
          && ReflectUtils.getAnnotatedConstructor(typeDescriptor.getRawType()) == null) {
        Optional<Field> finalField =
            types.stream()
                .flatMap(
                    fvti ->
                        Optional.ofNullable(fvti.getField()).map(Stream::of).orElse(Stream.empty()))
                .filter(f -> Modifier.isFinal(f.getModifiers()))
                .findAny();
        if (finalField.isPresent()) {
          throw new IllegalArgumentException(
              "Class "
                  + typeDescriptor
                  + " has final fields and no "
                  + "registered creator. Cannot use as schema, as we don't know how to create this "
                  + "object automatically");
        }
      }
      return types;
    }
  }

  private static void validateFieldNumbers(List<FieldValueTypeInformation> types) {
    for (int i = 0; i < types.size(); ++i) {
      FieldValueTypeInformation type = types.get(i);
      @Nullable Integer number = type.getNumber();
      if (number == null) {
        throw new RuntimeException("Unexpected null number for " + type.getName());
      }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the final modifier from the fields, or
  2. Register a creator method (static method annotated with @SchemaCreate returning an instance) with SchemaRegistry so Beam can construct objects.
  3. Alternatively annotate the class to use a different schema provider that supports immutables (e.g. @DefaultSchema(RecordSchema.class) or a custom SchemaUserTypeCreator).

Example fix

// before
public class User { private final String name; }

// after
public class User { private String name; }
// or register:
@SchemaCreate
public static User create(String name) { return new User(name); }
Defensive patterns

Strategy: validation

Validate before calling

// Java: ensure a creator exists when fields are final
boolean hasFinal = java.util.Arrays.stream(User.class.getDeclaredFields())
    .anyMatch(f -> java.lang.reflect.Modifier.isFinal(f.getModifiers()));
boolean hasCreator = java.util.Arrays.stream(User.class.getDeclaredMethods())
    .anyMatch(m -> m.isAnnotationPresent(org.apache.beam.sdk.schemas.annotations.SchemaCreate.class));
if (hasFinal && !hasCreator) throw new IllegalStateException("Register @SchemaCreate for final-field class");

Prevention

When it happens

Trigger: Registering or inferring JavaFieldSchema for a class that has final instance fields and no @SchemaCreate/creator method registered in SchemaRegistry.

Common situations: Immutable value classes (final fields set in constructor) used in PCollections without a custom schema provider; upgrading an existing class to make fields final.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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