apache/beam · error · IllegalArgumentException

Expected setter for property

Error message

Expected setter for property [%s] to not be marked with @%s on %s

What it means

Thrown when a setter for a property carries an annotation that is only allowed on the getter (e.g. @Default, @Description-adjacent property metadata). Beam derives such metadata exclusively from getters; annotating the setter is treated as a configuration error.

Solutions

  1. Remove the annotation from the setter named in the message.
  2. Ensure the equivalent annotation is present on the getter instead.
  3. Adopt the convention: property annotations go on getters only.

Example fix

// before
@Default.String("x") String getFoo();
@Default.String("x") void setFoo(String v);
// after
@Default.String("x") String getFoo();
void setFoo(String v);
Defensive patterns

Strategy: validation

Validate before calling

for (java.lang.reflect.Method m : MyOptions.class.getMethods()) {
  if (m.getName().startsWith("set") && m.getAnnotations().length > 0) {
    throw new IllegalStateException("Setter " + m.getName() + " should not carry property annotations");
  }
}

Try / catch

try {
  PipelineOptionsFactory.fromArgs(args).as(MyOptions.class);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("to not be marked with @")) { /* remove the annotation from the setter */ }
  throw e;
}

Prevention

When it happens

Trigger: PipelineOptionsFactory registration when throwForSettersWithTheAnnotation finds a setter whose property is marked with the annotation class: e.g. void setFoo(String) is annotated @Default.String("x") while the getter is the correct annotation target.

Common situations: IDE auto-annotating both accessor methods when the developer meant to annotate only the getter; copy-paste of the getter line including its annotations when writing the setter.

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


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

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java:1440

                "%n  - Expected for property [%s] to be marked on all %s, " + "found only on %s",
                getter.descriptor.getName(),
                getter.getterClassNames,
                getter.gettersWithTheAnnotationClassNames));
      }
      throw new IllegalArgumentException(errorBuilder.toString());
    }
  }

  private static class AnnotatedSetter {
    PropertyDescriptor descriptor;
    Iterable<String> settersWithTheAnnotationClassNames;
  }

  private static void throwForSettersWithTheAnnotation(
      List<AnnotatedSetter> setters, Class<? extends Annotation> annotationClass) {
    if (setters.size() == 1) {
      AnnotatedSetter setter = setters.get(0);
      throw new IllegalArgumentException(
          String.format(
              "Expected setter for property [%s] to not be marked with @%s on %s",
              setter.descriptor.getName(),
              annotationClass.getSimpleName(),
              setter.settersWithTheAnnotationClassNames));
    } else if (setters.size() > 1) {
      StringBuilder builder =
          new StringBuilder(
              String.format("Found setters marked with @%s:", annotationClass.getSimpleName()));
      for (AnnotatedSetter setter : setters) {
        builder.append(
            String.format(
                "%n  - Setter for property [%s] should not be marked with @%s on %s",
                setter.descriptor.getName(),
                annotationClass.getSimpleName(),
                setter.settersWithTheAnnotationClassNames));
      }
      throw new IllegalArgumentException(builder.toString());

View on GitHub (pinned to 12126d8942)