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.

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)

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.