{"record":{"id":"4a6ec93d980236a1","repo":"apache/beam","slug":"expected-getter-for-property-s-to-be-marked-with-s-on-all-s","errorCode":null,"errorMessage":"Expected getter for property [%s] to be marked with @%s on all %s, found only on %s","messagePattern":"Expected getter for property \\[(.+?)\\] to be marked with @(.+?) on all (.+?), found only on (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java","lineNumber":1405,"sourceCode":"            String.format(\n                \"%n  - Method [%s] has multiple definitions %s\",\n                errDef.method.getName(), errDef.collidingMethods));\n      }\n      throw new IllegalArgumentException(errorBuilder.toString());\n    }\n  }\n\n  private static class InconsistentlyAnnotatedGetters {\n    PropertyDescriptor descriptor;\n    Iterable<String> getterClassNames;\n    Iterable<String> gettersWithTheAnnotationClassNames;\n  }\n\n  private static void throwForGettersWithInconsistentAnnotation(\n      List<InconsistentlyAnnotatedGetters> getters, Class<? extends Annotation> annotationClass) {\n    if (getters.size() == 1) {\n      InconsistentlyAnnotatedGetters getter = getters.get(0);\n      throw new IllegalArgumentException(\n          String.format(\n              \"Expected getter for property [%s] to be marked with @%s on all %s, \"\n                  + \"found only on %s\",\n              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(),","sourceCodeStart":1387,"sourceCodeEnd":1423,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java#L1387-L1423","documentation":"Thrown when a property getter is expected to carry a given annotation (e.g. @Default, @Hidden, @Validation) on every interface that declares it, but the annotation is present on only some declarations. Beam requires annotation consistency across the hierarchy to derive reliable property metadata.","triggerScenarios":"PipelineOptionsFactory registration when throwForGettersWithInconsistentAnnotation finds one InconsistentlyAnnotatedGetters: getFoo() is annotated with e.g. @Default.String in sub-interface A but not in sub-interface B, both contributing the same property.","commonSituations":"Overriding a getter in a sub-interface without copying its annotation; adding an annotation to a base interface while stale un-annotated overrides exist elsewhere.","solutions":["Copy the named annotation onto the getter declarations listed as missing it.","Or remove the annotation everywhere so the property is uniformly unannotated.","Search the codebase for all declarations of the getter name and keep them identical."],"exampleFix":"// before\ninterface A extends PipelineOptions { @Default.String(\"x\") String getFoo(); }\ninterface B extends A { String getFoo(); }\n// after\ninterface A extends PipelineOptions { @Default.String(\"x\") String getFoo(); }\ninterface B extends A { @Default.String(\"x\") String getFoo(); }","handlingStrategy":"validation","validationCode":"for (java.lang.reflect.Method m : MyOptions.class.getMethods()) {\n  if (m.getName().equals(\"getFoo\")) {\n    if (m.getAnnotation(org.apache.beam.sdk.options.Default.String.class) == null) {\n      throw new IllegalStateException(\"getFoo in \" + m.getDeclaringClass() + \" missing @Default.String\");\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  PipelineOptionsFactory.fromArgs(args).as(MyOptions.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"to be marked with @\")) { /* copy the annotation to the listed declarations */ }\n  throw e;\n}","preventionTips":["When overriding a getter, copy all its annotations verbatim","Search all declarations of a getter before editing its annotations","Prefer single-declaration inheritance over per-interface re-declaration"],"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"}