bazelbuild/bazel · error · OptionProcessorException

Option must have an actual name.

Error message

Option must have an actual name.

What it means

The options annotation processor rejects an @Option annotation whose name attribute is the empty string. Every registered option needs a concrete flag name because the name is the key used for command-line lookup, expansion, and serialization; the processor enforces this at compile time before any code generation.

Source

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

      throw new OptionProcessorException(
          method, "Annotated method name must start with 'get' followed by an uppercase letter");
    }

    checkOptionName(method);
    checkOldCategoriesAreNotUsed(method);
    checkExpansionOptions(method);
    checkConverter(method);
    checkEffectTagRationality(method);
    checkMetadataTagAndCategoryRationality(method);
    checkNoDefaultValueForMultipleOption(method);
    checkDeprecated(method);
  }

  private void checkOptionName(ExecutableElement method) throws OptionProcessorException {
    Option annotation = method.getAnnotation(Option.class);
    String optionName = annotation.name();
    if (optionName.isEmpty()) {
      throw new OptionProcessorException(method, "Option must have an actual name.");
    }

    if (!ImmutableList.copyOf(annotation.metadataTags()).contains(OptionMetadataTag.INTERNAL)) {
      if (!Pattern.matches("([\\w:-])*", optionName)) {
        // Ideally, this would be just \w, but - and : are needed for legacy options. We can lie in
        // the error though, no harm in encouraging good behavior.
        throw new OptionProcessorException(
            method,
            "Options that are used on the command line as flags must have names made from word "
                + "characters only.");
      }
    }
  }

  private void checkEffectTagRationality(ExecutableElement method) throws OptionProcessorException {
    Option annotation = method.getAnnotation(Option.class);
    OptionEffectTag[] effectTags = annotation.effectTags();
    if (effectTags.length < 1) {

View on GitHub (pinned to e6e199d060)

Solutions

  1. Set an explicit name: @Option(name = "my_flag", ...)
  2. Choose the exact CLI spelling you want (snake_case by convention) since the name will not be derived from the getter
  3. Recompile to let the remaining checks (name charset, effect tags) run

Example fix

// before
@Option(name = "", defaultValue = "x", effectTags = {OptionEffectTag.NO_OP})
String getFoo();
// after
@Option(name = "foo", defaultValue = "x", effectTags = {OptionEffectTag.NO_OP})
String getFoo();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every @Option declares a non-empty name
for (var m : MyOptions.class.getMethods()) {
  Option o = m.getAnnotation(Option.class);
  if (o != null && o.name().isEmpty()) {
    throw new AssertionError("@Option on " + m + " has empty name");
  }
}

Prevention

When it happens

Trigger: Writing @Option(name = "", ...) or omitting a meaningful name while relying on some default that does not exist — the name has no implicit derivation from the method.

Common situations: Copying an annotation template and forgetting to fill in the name; refactor scripts that strip annotation values; assuming the flag name defaults to the method name.

Related errors


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