bazelbuild/bazel · error · OptionProcessorException

Option includes NO_OP with other effects. This doesn't make…

Error message

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.

What it means

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.

Solutions

  1. 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.
  2. If the option does have effects, remove NO_OP and keep the accurate effect tags.
  3. 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.
  4. Recompile to confirm the error is gone.

Example fix

// before (option kept for compat, does nothing)
@Option(
  name = "old_flag",
  defaultValue = "false",
  effectTags = {OptionEffectTag.NO_OP, OptionEffectTag.EAGER}
)
@Deprecated
// after
@Option(
  name = "old_flag",
  defaultValue = "false",
  effectTags = {OptionEffectTag.NO_OP},
  metadataTags = {OptionMetadataTag.DEPRECATED}
)
@Deprecated
Defensive patterns

Strategy: validation

Validate before calling

static void checkNoOpAlone(List<OptionEffectTag> tags) {
  if (tags.contains(OptionEffectTag.NO_OP)) {
    Preconditions.checkState(tags.size() == 1,
        "NO_OP must be the only effect tag, got: %s", tags);
  }
}

Prevention

When it happens

Trigger: 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}.

Common situations: 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.

Related errors


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/91186942bee7704e. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java:391

    Option annotation = method.getAnnotation(Option.class);
    OptionEffectTag[] effectTags = annotation.effectTags();
    if (effectTags.length < 1) {
      throw new OptionProcessorException(
          method,
          "Option does not list at least one OptionEffectTag. If the option has no effect, "
              + "please be explicit and add NO_OP. Otherwise, add a tag representing its effect.");
    } else if (effectTags.length > 1) {
      // If there are more than 1 tag, make sure that NO_OP and UNKNOWN is not one of them.
      // These don't make sense if other effects are listed.
      ImmutableList<OptionEffectTag> tags = ImmutableList.copyOf(effectTags);
      if (tags.contains(OptionEffectTag.UNKNOWN)) {
        throw new OptionProcessorException(
            method,
            "Option includes UNKNOWN with other, known, effects. Please remove UNKNOWN from "
                + "the list.");
      }
      if (tags.contains(OptionEffectTag.NO_OP)) {
        throw new OptionProcessorException(
            method,
            "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.");
      }
    }
  }

  private void checkMetadataTagAndCategoryRationality(ExecutableElement method)
      throws OptionProcessorException {
    Option annotation = method.getAnnotation(Option.class);
    OptionMetadataTag[] metadataTags = annotation.metadataTags();
    OptionDocumentationCategory category = annotation.documentationCategory();

    for (OptionMetadataTag tag : metadataTags) {
      if (tag == OptionMetadataTag.HIDDEN || tag == OptionMetadataTag.INTERNAL) {
        if (category != OptionDocumentationCategory.UNDOCUMENTED) {
          throw new OptionProcessorException(
              method,

View on GitHub (pinned to e6e199d060)