{"record":{"id":"91186942bee7704e","repo":"bazelbuild/bazel","slug":"option-includes-no-op-with-other-effects-this-doe","errorCode":null,"errorMessage":"Option includes NO_OP with other effects. This doesn't make much sense. Please remove NO_OP or the actual effects from the list, whichever is correct.","messagePattern":"Option includes NO_OP with other effects\\. This doesn't make much sense\\. Please remove NO_OP or the actual effects from the list, whichever is correct\\.","errorType":"validation","errorClass":"OptionProcessorException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java","lineNumber":391,"sourceCode":"    Option annotation = method.getAnnotation(Option.class);\n    OptionEffectTag[] effectTags = annotation.effectTags();\n    if (effectTags.length < 1) {\n      throw new OptionProcessorException(\n          method,\n          \"Option does not list at least one OptionEffectTag. If the option has no effect, \"\n              + \"please be explicit and add NO_OP. Otherwise, add a tag representing its effect.\");\n    } else if (effectTags.length > 1) {\n      // If there are more than 1 tag, make sure that NO_OP and UNKNOWN is not one of them.\n      // These don't make sense if other effects are listed.\n      ImmutableList<OptionEffectTag> tags = ImmutableList.copyOf(effectTags);\n      if (tags.contains(OptionEffectTag.UNKNOWN)) {\n        throw new OptionProcessorException(\n            method,\n            \"Option includes UNKNOWN with other, known, effects. Please remove UNKNOWN from \"\n                + \"the list.\");\n      }\n      if (tags.contains(OptionEffectTag.NO_OP)) {\n        throw new OptionProcessorException(\n            method,\n            \"Option includes NO_OP with other effects. This doesn't make much sense. Please \"\n                + \"remove NO_OP or the actual effects from the list, whichever is correct.\");\n      }\n    }\n  }\n\n  private void checkMetadataTagAndCategoryRationality(ExecutableElement method)\n      throws OptionProcessorException {\n    Option annotation = method.getAnnotation(Option.class);\n    OptionMetadataTag[] metadataTags = annotation.metadataTags();\n    OptionDocumentationCategory category = annotation.documentationCategory();\n\n    for (OptionMetadataTag tag : metadataTags) {\n      if (tag == OptionMetadataTag.HIDDEN || tag == OptionMetadataTag.INTERNAL) {\n        if (category != OptionDocumentationCategory.UNDOCUMENTED) {\n          throw new OptionProcessorException(\n              method,","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java#L373-L409","documentation":"This compile-time error comes from Bazel's options annotation processor. It fires when an @Option method lists NO_OP in effectTags alongside other effect tags. NO_OP means the option has no effect, which contradicts the other listed effects, so the processor rejects the combination.","triggerScenarios":"An @Option method with effectTags containing NO_OP and at least one other tag (effectTags.length > 1), e.g. effectTags = {OptionEffectTag.NO_OP, OptionEffectTag.EAGER}.","commonSituations":"Converting a real option into a no-op (e.g. a deprecated flag kept for compatibility) while forgetting to strip its old effect tags; adding NO_OP 'for safety' next to genuine tags; copying an option definition and toggling it to no-op without cleaning up effectTags.","solutions":["If the option really does nothing now, keep only NO_OP: effectTags = {OptionEffectTag.NO_OP} (a single tag is fine) and remove all other tags.","If the option does have effects, remove NO_OP and keep the accurate effect tags.","Note that a NO_OP option will additionally be required by the processor to be @Deprecated or carry metadata tag HIDDEN/INTERNAL (see the no-op check), so add those as appropriate.","Recompile to confirm the error is gone."],"exampleFix":"// before (option kept for compat, does nothing)\n@Option(\n  name = \"old_flag\",\n  defaultValue = \"false\",\n  effectTags = {OptionEffectTag.NO_OP, OptionEffectTag.EAGER}\n)\n@Deprecated\n// after\n@Option(\n  name = \"old_flag\",\n  defaultValue = \"false\",\n  effectTags = {OptionEffectTag.NO_OP},\n  metadataTags = {OptionMetadataTag.DEPRECATED}\n)\n@Deprecated","handlingStrategy":"validation","validationCode":"static void checkNoOpAlone(List<OptionEffectTag> tags) {\n  if (tags.contains(OptionEffectTag.NO_OP)) {\n    Preconditions.checkState(tags.size() == 1,\n        \"NO_OP must be the only effect tag, got: %s\", tags);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When retiring a flag to no-op, strip its old effectTags in the same change.","Pair a NO_OP option with @Deprecated and metadataTags DEPRECATED (or HIDDEN/INTERNAL) to satisfy the related no-op check."],"tags":["java","bazel","annotation-processing","options","compile-time","option-effect-tags","deprecation"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}