apache/beam · error · RuntimeException
@SchemaFieldNumber can only be used on getters in Java Beans
Error message
@SchemaFieldNumber can only be used on getters in Java Beans. Found on setter '%s'
What it means
Thrown by JavaBeanSchema.get when a setter method carries @SchemaFieldNumber. In Java Beans, schema metadata annotations like @SchemaFieldNumber must appear on the getter only; placing it on the setter is rejected to prevent conflicting definitions.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/JavaBeanSchema.java:119
/** {@link FieldValueTypeSupplier} that's based on setter methods. */
@VisibleForTesting
public static class SetterTypeSupplier implements FieldValueTypeSupplier {
private static final SetterTypeSupplier INSTANCE = new SetterTypeSupplier();
@Override
public List<FieldValueTypeInformation> get(TypeDescriptor<?> typeDescriptor) {
return ReflectUtils.getMethods(typeDescriptor.getRawType()).stream()
.filter(ReflectUtils::isSetter)
.filter(m -> !m.isAnnotationPresent(SchemaIgnore.class))
.map(m -> FieldValueTypeInformation.forSetter(typeDescriptor, m))
.map(
t -> {
Method m =
Preconditions.checkNotNull(
t.getMethod(), JavaBeanUtils.SETTER_WITH_NULL_METHOD_ERROR);
if (m.getAnnotation(SchemaFieldNumber.class) != null) {
throw new RuntimeException(
String.format(
"@SchemaFieldNumber can only be used on getters in Java Beans. Found on"
+ " setter '%s'",
m.getName()));
}
if (m.getAnnotation(SchemaFieldName.class) != null) {
throw new RuntimeException(
String.format(
"@SchemaFieldName can only be used on getters in Java Beans. Found on"
+ " setter '%s'",
m.getName()));
}
if (m.getAnnotation(SchemaCaseFormat.class) != null) {
throw new RuntimeException(
String.format(
"@SchemaCaseFormat can only be used on getters in Java Beans. Found on"
+ " setter '%s'",
m.getName()));View on GitHub (pinned to 12126d8942)
Solutions
- Move @SchemaFieldNumber from the setter to the corresponding getter.
- Remove the annotation from the setter entirely — it is ignored/invalid there by design.
Example fix
// before
@SchemaFieldNumber(0)
public void setName(String name) { ... }
// after
public void setName(String name) { ... }
// (keep @SchemaFieldNumber(0) on getName()) Defensive patterns
Strategy: validation
Validate before calling
for (Method m : clazz.getMethods()) { if (m.getParameterCount() == 1 && m.isAnnotationPresent(SchemaFieldNumber.class)) { throw new IllegalStateException("@SchemaFieldNumber must be on the getter of " + m.getName().substring(3)); } } Try / catch
try { schemaOf(clazz); } catch (RuntimeException e) { if (e.getMessage().contains("@SchemaFieldNumber can only be used on getters")) { /* move annotation to getter */ } else { throw e; } } Prevention
- Put all schema annotations (@SchemaFieldNumber, @SchemaFieldName, @SchemaCaseFormat) on getters only.
- Configure code generators to emit annotations on getters.
- Scan for annotations on setters in a unit test.
When it happens
Trigger: Annotating a setter (e.g. setName) with @SchemaFieldNumber; schema registration then introspects setter methods and throws this exception.
Common situations: Copy-pasting annotations from getters to setters; codegen generating symmetric annotations; misunderstanding that annotations belong on setters.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- @SchemaFieldName can only be used on getters in Java Beans.
- Cannot define both @SchemaFieldName and @SchemaCaseFormat. F
- Getter has wrong prefix <method>
- Setter methods should take a single argument <method>
- Setter has wrong prefix <method>
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b1be4f120076e4a8.
Report an issue: GitHub.