apache/beam · error · RuntimeException

Cannot define both @SchemaFieldName and @SchemaCaseFormat. F

Error message

Cannot define both @SchemaFieldName and @SchemaCaseFormat. From member '%s'.

What it means

Thrown by getNameOverride while resolving a schema field's name: a class member is annotated with both @SchemaFieldName and @SchemaCaseFormat (on the member itself), which is contradictory — one specifies an explicit name and the other specifies a case transform for the derived name. Beam rejects the ambiguous configuration.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/FieldValueTypeInformation.java:169

  }

  public static <T extends AnnotatedElement & Member> int getNumberOverride(int index, T member) {
    @Nullable SchemaFieldNumber fieldNumber = member.getAnnotation(SchemaFieldNumber.class);
    if (fieldNumber == null) {
      return index;
    }
    return Integer.parseInt(fieldNumber.value());
  }

  public static <T extends AnnotatedElement & Member> String getNameOverride(
      String original, T member) {
    @Nullable SchemaFieldName fieldName = member.getAnnotation(SchemaFieldName.class);
    @Nullable SchemaCaseFormat caseFormatAnnotation = member.getAnnotation(SchemaCaseFormat.class);
    @Nullable SchemaCaseFormat classCaseFormatAnnotation =
        member.getDeclaringClass().getAnnotation(SchemaCaseFormat.class);
    if (fieldName != null) {
      if (caseFormatAnnotation != null) {
        throw new RuntimeException(
            String.format(
                "Cannot define both @SchemaFieldName and @SchemaCaseFormat. From member '%s'.",
                member.getName()));
      }
      return fieldName.value();
    } else if (caseFormatAnnotation != null) {
      return CaseFormat.LOWER_CAMEL.to(caseFormatAnnotation.value(), original);
    } else if (classCaseFormatAnnotation != null) {
      return CaseFormat.LOWER_CAMEL.to(classCaseFormatAnnotation.value(), original);
    } else {
      return original;
    }
  }

  public static <T extends AnnotatedElement & Member> @Nullable String getFieldDescription(
      T member) {
    @Nullable SchemaFieldDescription fieldDescription =
        member.getAnnotation(SchemaFieldDescription.class);

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove @SchemaCaseFormat from the member and keep @SchemaFieldName with the exact desired name.
  2. Or remove @SchemaFieldName and let @SchemaCaseFormat transform the member's Java name.
  3. If class-level @SchemaCaseFormat is intended, only the member-level @SchemaFieldName conflicts — keep the member annotation and delete the redundant member-level case format.

Example fix

// before
@SchemaFieldName("user_id")
@SchemaCaseFormat(CaseFormat.LOWER_SNAKE)
private String getUserId();

// after
@SchemaFieldName("user_id")
private String getUserId();
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : clazz.getDeclaredMethods()) { if (m.isAnnotationPresent(SchemaFieldName.class) && m.isAnnotationPresent(SchemaCaseFormat.class)) { throw new IllegalStateException("Member " + m.getName() + " has both @SchemaFieldName and @SchemaCaseFormat"); } }

Try / catch

try { Schema.of(clazz); } catch (RuntimeException e) { if (e.getMessage().contains("Cannot define both @SchemaFieldName and @SchemaCaseFormat")) { /* remove one annotation */ } else { throw e; } }

Prevention

When it happens

Trigger: Annotating a getter/setter/field with both @SchemaFieldName("x") and @SchemaCaseFormat(CaseFormat.LOWER_CAMEL); schema introspection of the class then throws from getNameOverride via forField/forGetter.

Common situations: Copy-paste annotations during refactors; mixing naming conventions on the same field after team-wide renaming; Lombok or codegen emitting both annotations.

Related errors


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