{"record":{"id":"2689a81a173fd73a","repo":"apache/beam","slug":"property-getters-are-inconsistently-marked-with-s","errorCode":null,"errorMessage":"Property getters are inconsistently marked with @%s:","messagePattern":"Property getters are inconsistently marked with @(.+?):","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java","lineNumber":1427,"sourceCode":"              getter.descriptor.getName(),\n              annotationClass.getSimpleName(),\n              getter.getterClassNames,\n              getter.gettersWithTheAnnotationClassNames));\n    } else if (getters.size() > 1) {\n      StringBuilder errorBuilder =\n          new StringBuilder(\n              String.format(\n                  \"Property getters are inconsistently marked with @%s:\",\n                  annotationClass.getSimpleName()));\n      for (InconsistentlyAnnotatedGetters getter : getters) {\n        errorBuilder.append(\n            String.format(\n                \"%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));","sourceCodeStart":1409,"sourceCodeEnd":1445,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java#L1409-L1445","documentation":"The aggregated variant of the inconsistent-getter-annotation error: when multiple properties have inconsistently applied annotations, Beam throws a single message 'Property getters are inconsistently marked with @%s:' listing each offending property line by line.","triggerScenarios":"PipelineOptionsFactory registration when throwForGettersWithInconsistentAnnotation receives getters.size() > 1; a builder appends one '%n - Expected for property [...] to be marked on all [...] found only on [...]' line per property before throwing.","commonSituations":"Bulk annotation passes (@Default, @Hidden) applied to some but not all overriding getters; code reviews missing inherited declarations of the same property.","solutions":["Fix each listed property so its annotation is present (or absent) on every declaration in the hierarchy.","Use an IDE 'find usages' on each getter name to locate all declarations.","Consider defining the annotated getter once in the most-derived interface and inheriting it."],"exampleFix":"// before\ninterface A extends PipelineOptions { @Default.String(\"x\") String getFoo(); String getBar(); }\ninterface B extends A { String getFoo(); @Default.Integer(1) int getBar(); }\n// after\ninterface A extends PipelineOptions { @Default.String(\"x\") String getFoo(); @Default.Integer(1) int getBar(); }\ninterface B extends A {}","handlingStrategy":"validation","validationCode":"// Check annotation consistency for every getter across the hierarchy before registration:\njava.util.Map<String, java.util.Set<Boolean>> marks = new java.util.HashMap<>();\nfor (java.lang.reflect.Method m : MyOptions.class.getMethods()) {\n  if (m.getName().startsWith(\"get\")) {\n    marks.computeIfAbsent(m.getName(), k -> new java.util.HashSet<>())\n         .add(m.getAnnotations().length > 0);\n  }\n}\nmarks.forEach((n, s) -> { if (s.size() > 1) System.err.println(\"inconsistent annotations on \" + n); });","typeGuard":null,"tryCatchPattern":"try {\n  PipelineOptionsFactory.fromArgs(args).as(MyOptions.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"inconsistently marked with @\")) { /* fix each listed property */ }\n  throw e;\n}","preventionTips":["Apply annotation changes to all overriding declarations in one commit","Use IDE 'find usages' before adding/removing an annotation on a getter","Validate options interfaces in a unit test at build time"],"tags":["java","apache-beam","pipeline-options","annotation-validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}