bazelbuild/bazel · error · OptionProcessorException
Documentation level is no longer read from the option catego
Error message
Documentation level is no longer read from the option category. Category "%s" is disallowed, see OptionMetadataTags for the relevant tags.
What it means
This compile-time error is produced by Bazel's options annotation processor. The old API encoded documentation level (undocumented/hidden/internal) as free-form strings in the option's category attribute; that mechanism was replaced by OptionMetadataTag (HIDDEN, INTERNAL, etc.) and OptionDocumentationCategory. The processor maintains an allowlist-free blocklist of the legacy category strings and rejects any option still using one.
Source
Thrown at src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java:424
if (tag == OptionMetadataTag.HIDDEN || tag == OptionMetadataTag.INTERNAL) {
if (category != OptionDocumentationCategory.UNDOCUMENTED) {
throw new OptionProcessorException(
method,
"Option has metadata tag %s but does not have category UNDOCUMENTED. Please fix.",
tag);
}
}
}
}
private static final ImmutableSet<String> DEPRECATED_CATEGORIES =
ImmutableSet.of("undocumented", "hidden", "internal");
private void checkOldCategoriesAreNotUsed(ExecutableElement method)
throws OptionProcessorException {
Option annotation = method.getAnnotation(Option.class);
if (DEPRECATED_CATEGORIES.contains(annotation.category())) {
throw new OptionProcessorException(
method,
"Documentation level is no longer read from the option category. Category \""
+ annotation.category()
+ "\" is disallowed, see OptionMetadataTags for the relevant tags.");
}
}
private void checkExpansionOptions(ExecutableElement method) throws OptionProcessorException {
Option annotation = method.getAnnotation(Option.class);
boolean isExpansion = annotation.expansion().length > 0;
boolean hasImplicitRequirements = annotation.implicitRequirements().length > 0;
if (isExpansion && hasImplicitRequirements) {
throw new OptionProcessorException(
method,
"Can't set an option to be both an expansion option and have implicit requirements.");
}
View on GitHub (pinned to e6e199d060)
Solutions
- Remove the category = "..." parameter from the @Option annotation.
- Express documentation level via metadataTags: use OptionMetadataTag.HIDDEN or OptionMetadataTag.INTERNAL instead of the old category strings.
- Set documentationCategory = OptionDocumentationCategory.UNDOCUMENTED for hidden/internal options (required by the related metadata check).
- For all other options, choose an accurate OptionDocumentationCategory value describing where the flag belongs in generated docs.
Example fix
// before
@Option(
name = "legacy_hidden_flag",
defaultValue = "true",
category = "hidden",
effectTags = {OptionEffectTag.NO_OP}
)
// after
@Option(
name = "legacy_hidden_flag",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.NO_OP},
metadataTags = {OptionMetadataTag.HIDDEN}
) Defensive patterns
Strategy: validation
Validate before calling
// Reject legacy category strings before writing options code
private static final Set<String> LEGACY = Set.of("undocumented", "hidden", "internal");
static String assertModernCategory(String category) {
Preconditions.checkArgument(!LEGACY.contains(category),
"Legacy category '%s' removed; use OptionMetadataTag instead", category);
return category;
} Prevention
- Search options sources for category = " at every upgrade of the options library.
- New options should never set the category attribute at all — use documentationCategory and metadataTags.
When it happens
Trigger: An @Option method whose category() attribute (or the @Option annotation's category parameter) is exactly "undocumented", "hidden", or "internal" — the strings in DEPRECATED_CATEGORIES.
Common situations: Upgrading Bazel or the options library to a version where the category-based scheme was removed; porting old options classes written against the pre-migration API; merging legacy code that predates OptionMetadataTag.
Related errors
- Option includes UNKNOWN with other, known, effects. Please r
- Option includes NO_OP with other effects. This doesn't make
- Option has metadata tag %s but does not have category UNDOCU
- Can't set an option to be both an expansion option and have
- Can't set an option to accumulate multiple values and let it
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/5430f11b278ec774.
Report an issue: GitHub.