bazelbuild/bazel · error · OptionProcessorException

Option includes UNKNOWN with other, known, effects. Please r

Error message

Option includes UNKNOWN with other, known, effects. Please remove UNKNOWN from the list.

What it means

This error is thrown at compile time by the annotation processor that validates @Option-annotated methods in Bazel options classes. It means the option declares more than one OptionEffectTag in effectTags and one of them is UNKNOWN. UNKNOWN is a placeholder meaning 'the effect has not been categorized yet', so mixing it with concrete effects is contradictory and rejected.

Source

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

                + "characters only.");
      }
    }
  }

  private void checkEffectTagRationality(ExecutableElement method) throws OptionProcessorException {
    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();

View on GitHub (pinned to e6e199d060)

Solutions

  1. Open the flagged @Option method and inspect its effectTags array.
  2. Decide which single concrete effect(s) apply (e.g. EAGER, LAZY, LOSES_INCREMENTAL_STATE, CHANGES_INPUTS) and remove OptionEffectTag.UNKNOWN from the list.
  3. If genuinely no effect is known, leave UNKNOWN as the ONLY tag (length 1 does not trigger this error), or use NO_OP alone if the option intentionally does nothing.
  4. Recompile; the processor error disappears once UNKNOWN is not combined with other tags.

Example fix

// before
@Option(
  name = "experimental_foo",
  defaultValue = "false",
  documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
  effectTags = {OptionEffectTag.UNKNOWN, OptionEffectTag.CHANGES_INPUTS},
  metadataTags = {OptionMetadataTag.EXPERIMENTAL}
)
// after
@Option(
  name = "experimental_foo",
  defaultValue = "false",
  documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
  effectTags = {OptionEffectTag.CHANGES_INPUTS},
  metadataTags = {OptionMetadataTag.EXPERIMENTAL}
)
Defensive patterns

Strategy: validation

Validate before calling

// Before adding effectTags, assert UNKNOWN appears alone or not at all
static List<OptionEffectTag> sanitizeEffects(List<OptionEffectTag> tags) {
  if (tags.size() > 1) {
    Preconditions.checkState(!tags.contains(OptionEffectTag.UNKNOWN),
        "UNKNOWN must not be combined with other OptionEffectTags: %s", tags);
  }
  return tags;
}

Prevention

When it happens

Trigger: An @Option method whose effectTags attribute contains UNKNOWN together with at least one other tag, e.g. @Option(name = "foo", effectTags = {OptionEffectTag.UNKNOWN, OptionEffectTag.EAGER}). The check only fires when effectTags.length > 1.

Common situations: Copying an existing option that used UNKNOWN and then adding a real effect tag without removing UNKNOWN; auto-completing OptionEffectTag entries in an IDE and accidentally keeping UNKNOWN; migrating legacy options that were never properly tagged.

Related errors


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