bazelbuild/bazel · error · OptionProcessorException
Option has metadata tag %s but does not have category UNDOCU
Error message
Option has metadata tag %s but does not have category UNDOCUMENTED. Please fix.
What it means
Thrown at compile time by Bazel's options annotation processor while validating the relationship between an option's metadataTags and its documentationCategory. Options marked with metadata tag HIDDEN or INTERNAL must use documentationCategory = UNDOCUMENTED, because hidden/internal options are by definition excluded from generated documentation.
Source
Thrown at src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java:408
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,
"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 \""View on GitHub (pinned to e6e199d060)
Solutions
- Set documentationCategory = OptionDocumentationCategory.UNDOCUMENTED on the flagged option (this is the intended fix in essentially all cases).
- Alternatively, if the option should stay documented, remove the HIDDEN/INTERNAL metadata tag that forced the mismatch.
- Recompile; the check re-runs on every build of the options class.
Example fix
// before
@Option(
name = "internal_cache_size",
defaultValue = "1024",
documentationCategory = OptionDocumentationCategory.PERFORMANCE,
effectTags = {OptionEffectTag.EAGER},
metadataTags = {OptionMetadataTag.INTERNAL}
)
// after
@Option(
name = "internal_cache_size",
defaultValue = "1024",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.EAGER},
metadataTags = {OptionMetadataTag.INTERNAL}
) Defensive patterns
Strategy: validation
Validate before calling
static void checkCategoryMatchesMetadata(OptionDocumentationCategory category,
Set<OptionMetadataTag> metadataTags) {
if (metadataTags.contains(HIDDEN) || metadataTags.contains(INTERNAL)) {
Preconditions.checkState(category == OptionDocumentationCategory.UNDOCUMENTED,
"HIDDEN/INTERNAL options must use UNDOCUMENTED category");
}
} Prevention
- When adding HIDDEN or INTERNAL to an option, always flip documentationCategory to UNDOCUMENTED in the same edit.
- Write options with metadataTags first, then choose the category — the category follows from the tags.
When it happens
Trigger: An @Option method with metadataTags containing OptionMetadataTag.HIDDEN or OptionMetadataTag.INTERNAL while documentationCategory is anything other than UNDOCUMENTED, e.g. documentationCategory = OptionDocumentationCategory.LOGGING with metadataTags = {OptionMetadataTag.INTERNAL}.
Common situations: Marking a previously-documented option as HIDDEN or INTERNAL but forgetting to flip its documentationCategory to UNDOCUMENTED; writing a new internal option by copying a documented one and only changing metadataTags; refactoring flags between categories during cleanup.
Related errors
- Options with metadata tag DEPRECATED must be annotated with
- Options annotated with @Deprecated must have metadata tag DE
- Option includes UNKNOWN with other, known, effects. Please r
- Option includes NO_OP with other effects. This doesn't make
- Documentation level is no longer read from the option catego
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/dc1c2c6f53f22039.
Report an issue: GitHub.