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
- Remove the final modifier from the fields, or
- Register a creator method (static method annotated with @SchemaCreate returning an instance) with SchemaRegistry so Beam can construct objects.
- 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
- Prefer non-final fields or register @SchemaCreate for immutable classes.
- Test schema inference for new POJOs before deploying pipelines.
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
- Unable to generate coder for schema {schema}
- Unable to generate a creator for class ${builderClass} with
- Creator parameter ${paramName} Doesn't correspond to a schem
- Unable to generate
- Could not find a matching method in transform for BuilderMe
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4829997bef5ae057.
Report an issue: GitHub.