{"record":{"id":"2a7a582e681e86fb","repo":"apache/beam","slug":"all-inherited-interfaces-of-s-should-inherit-from-the","errorCode":null,"errorMessage":"All inherited interfaces of [%s] should inherit from the PipelineOptions interface. The following inherited interfaces do not:%n - %s","messagePattern":"All inherited interfaces of \\[(.+?)\\] should inherit from the PipelineOptions interface\\. The following inherited interfaces do not:%n - (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java","lineNumber":1353,"sourceCode":"\n    for (Class<?> klass : checkClass.getInterfaces()) {\n      checkInheritedFrom(klass, fromClass, nonPipelineOptions);\n    }\n  }\n\n  private static void throwNonPipelineOptions(\n      Class<?> klass, Set<Class<?>> nonPipelineOptionsClasses) {\n    StringBuilder errorBuilder =\n        new StringBuilder(\n            String.format(\n                \"All inherited interfaces of [%s] should inherit from the PipelineOptions\"\n                    + \" interface. The following inherited interfaces do not:\",\n                klass.getName()));\n\n    for (Class<?> invalidKlass : nonPipelineOptionsClasses) {\n      errorBuilder.append(String.format(\"%n - %s\", invalidKlass.getName()));\n    }\n    throw new IllegalArgumentException(errorBuilder.toString());\n  }\n\n  private static void validateInheritedInterfacesExtendPipelineOptions(Class<?> klass) {\n    Set<Class<?>> nonPipelineOptionsClasses = new LinkedHashSet<>();\n    checkInheritedFrom(klass, PipelineOptions.class, nonPipelineOptionsClasses);\n\n    if (!nonPipelineOptionsClasses.isEmpty()) {\n      throwNonPipelineOptions(klass, nonPipelineOptionsClasses);\n    }\n  }\n\n  private static class MultipleDefinitions {\n    private Method method;\n    private SortedSet<Method> collidingMethods;\n  }\n\n  private static void throwForMultipleDefinitions(\n      Class<? extends PipelineOptions> iface, List<MultipleDefinitions> definitions) {","sourceCodeStart":1335,"sourceCodeEnd":1371,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java#L1335-L1371","documentation":"Thrown when a PipelineOptions interface (or any interface it extends, transitively) inherits from interfaces that do not extend PipelineOptions. Beam requires the whole interface hierarchy to descend from PipelineOptions so it can enumerate properties and build the proxy implementation.","triggerScenarios":"PipelineOptionsFactory.fromArgs(...).as(Klass.class) or .create() where validateInheritedInterfacesExtendPipelineOptions finds nonPipelineOptionsClasses: Klass extends a plain (non-PipelineOptions) Java interface.","commonSituations":"Extracting shared getters into a common utility interface and extending it without adding 'extends PipelineOptions'; reusing a DTO interface as an options interface; refactoring where the base interface's extends clause was dropped.","solutions":["Make the offending interface listed in the message extend PipelineOptions.","Or stop extending it and duplicate/move the needed getters directly into the options interface.","Keep every interface in the options hierarchy rooted at PipelineOptions going forward."],"exampleFix":"// before\ninterface Common {\n  String getFoo();\n}\ninterface MyOptions extends PipelineOptions, Common {}\n// after\ninterface Common extends PipelineOptions {\n  String getFoo();\n}\ninterface MyOptions extends PipelineOptions, Common {}","handlingStrategy":"validation","validationCode":"static void assertAllExtend(Class<?> klass) {\n  for (Class<?> i : klass.getInterfaces()) {\n    if (!PipelineOptions.class.isAssignableFrom(i)) {\n      throw new IllegalStateException(i.getName() + \" must extend PipelineOptions\");\n    }\n    assertAllExtend(i);\n  }\n}","typeGuard":"static boolean isPipelineOptionsHierarchy(Class<?> k) {\n  return PipelineOptions.class.isAssignableFrom(k);\n}","tryCatchPattern":"try {\n  PipelineOptionsFactory.fromArgs(args).as(MyOptions.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"should inherit from the PipelineOptions\")) { /* fix interface hierarchy */ }\n  throw e;\n}","preventionTips":["Always declare shared option interfaces as 'interface X extends PipelineOptions'","Never reuse plain DTO interfaces as options parents","Review 'extends' clauses when extracting common getters into a base interface"],"tags":["java","apache-beam","pipeline-options","interface-hierarchy"],"backgroundTag":"type-mismatch","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"}