{"record":{"id":"6e3ba42e57ac8230","repo":"apache/beam","slug":"expected-setter-for-property-s-to-not-be-marked-with-s-on-s","errorCode":null,"errorMessage":"Expected setter for property [%s] to not be marked with @%s on %s","messagePattern":"Expected setter for property \\[(.+?)\\] to not be marked with @(.+?) on (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java","lineNumber":1440,"sourceCode":"                \"%n  - Expected for property [%s] to be marked on all %s, \" + \"found only on %s\",\n                getter.descriptor.getName(),\n                getter.getterClassNames,\n                getter.gettersWithTheAnnotationClassNames));\n      }\n      throw new IllegalArgumentException(errorBuilder.toString());\n    }\n  }\n\n  private static class AnnotatedSetter {\n    PropertyDescriptor descriptor;\n    Iterable<String> settersWithTheAnnotationClassNames;\n  }\n\n  private static void throwForSettersWithTheAnnotation(\n      List<AnnotatedSetter> setters, Class<? extends Annotation> annotationClass) {\n    if (setters.size() == 1) {\n      AnnotatedSetter setter = setters.get(0);\n      throw new IllegalArgumentException(\n          String.format(\n              \"Expected setter for property [%s] to not be marked with @%s on %s\",\n              setter.descriptor.getName(),\n              annotationClass.getSimpleName(),\n              setter.settersWithTheAnnotationClassNames));\n    } else if (setters.size() > 1) {\n      StringBuilder builder =\n          new StringBuilder(\n              String.format(\"Found setters marked with @%s:\", annotationClass.getSimpleName()));\n      for (AnnotatedSetter setter : setters) {\n        builder.append(\n            String.format(\n                \"%n  - Setter for property [%s] should not be marked with @%s on %s\",\n                setter.descriptor.getName(),\n                annotationClass.getSimpleName(),\n                setter.settersWithTheAnnotationClassNames));\n      }\n      throw new IllegalArgumentException(builder.toString());","sourceCodeStart":1422,"sourceCodeEnd":1458,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java#L1422-L1458","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove the annotation from the setter named in the message.","Ensure the equivalent annotation is present on the getter instead.","Adopt the convention: property annotations go on getters only."],"exampleFix":"// before\n@Default.String(\"x\") String getFoo();\n@Default.String(\"x\") void setFoo(String v);\n// after\n@Default.String(\"x\") String getFoo();\nvoid setFoo(String v);","handlingStrategy":"validation","validationCode":"for (java.lang.reflect.Method m : MyOptions.class.getMethods()) {\n  if (m.getName().startsWith(\"set\") && m.getAnnotations().length > 0) {\n    throw new IllegalStateException(\"Setter \" + m.getName() + \" should not carry property annotations\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  PipelineOptionsFactory.fromArgs(args).as(MyOptions.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"to not be marked with @\")) { /* remove the annotation from the setter */ }\n  throw e;\n}","preventionTips":["Never copy getter annotations onto setters","Adopt the getter-only annotation convention in code review checklists","Configure IDE code generation to not duplicate annotations on setters"],"tags":["java","apache-beam","pipeline-options","annotation-target"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}