bazelbuild/bazel · error · OptionProcessorException
Option that allows multiple occurrences must be of type %s,
Error message
Option that allows multiple occurrences must be of type %s, but is of type %s
What it means
The first of three shape checks the Bazel options annotation processor runs on options with allowMultiple = true: the option's return (field) type must be a declared type (a class or interface such as List), not a primitive, array, or type variable. Repeatable options must accumulate values into a List-like declared type.
Source
Thrown at src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java:577
if (typeUtils.isSameType(converterElement.asType(), defaultConverterElement.asType())) {
// Find a matching converter in the default converter list, and check that it successfully
// parses the default value for this option.
checkForDefaultConverter(method, acceptedConverterReturnTypes, annotation.defaultValue());
} else {
// Check that the provided converter has an accepted return type.
checkProvidedConverter(method, acceptedConverterReturnTypes, converterElement);
}
}
private ImmutableList<TypeMirror> getAcceptedConverterReturnTypes(ExecutableElement method)
throws OptionProcessorException {
TypeMirror optionType = method.getReturnType();
Option annotation = method.getAnnotation(Option.class);
TypeMirror listType = elementUtils.getTypeElement(List.class.getCanonicalName()).asType();
if (annotation.allowMultiple()) {
if (optionType.getKind() != TypeKind.DECLARED) {
throw new OptionProcessorException(
method,
"Option that allows multiple occurrences must be of type %s, but is of type %s",
listType,
optionType);
}
DeclaredType optionDeclaredType = (DeclaredType) optionType;
if (!typeUtils.isAssignable(typeUtils.erasure(optionDeclaredType), listType)) {
throw new OptionProcessorException(
method,
"Option that allows multiple occurrences must be assignable to type %s, but is of type"
+ " %s",
listType,
optionType);
}
List<? extends TypeMirror> genericParameters = optionDeclaredType.getTypeArguments();
if (genericParameters.size() != 1) {
throw new OptionProcessorException(
method,View on GitHub (pinned to e6e199d060)
Solutions
- Change the option's type to List<E> (or a subtype), where E is the per-occurrence value type, e.g. List<String>.
- Ensure any generic base class resolves the option type to a concrete declared type; type variables never satisfy the check.
- Remember defaultValue must be "null" for allowMultiple options (separate check).
- Recompile to confirm.
Example fix
// before @Option( name = "tag", defaultValue = "null", allowMultiple = true ) public static String tag; // after @Option( name = "tag", defaultValue = "null", allowMultiple = true ) public static List<String> tag;
Defensive patterns
Strategy: type-guard
Validate before calling
static void checkMultipleIsDeclaredType(boolean allowMultiple, TypeMirror t) {
if (allowMultiple) {
Preconditions.checkState(t.getKind() == TypeKind.DECLARED,
"allowMultiple options must be a declared List type, got kind %s", t.getKind());
}
} Type guard
// Runtime/reflection analogue: repeatable options must be a class/interface type
static boolean isRepeatableOptionType(Class<?> clazz) {
return !clazz.isPrimitive() && !clazz.isArray();
} Prevention
- Always declare allowMultiple options as List<E> — primitives, arrays, and type variables are never valid.
- In generic base option classes, bind the option type to a concrete List<E> in subclasses.
When it happens
Trigger: @Option(allowMultiple = true) on a method whose type's TypeKind is not DECLARED — e.g. boolean, int, or a generic type variable T used in an abstract base options class.
Common situations: Switching a flag to allowMultiple without changing its primitive/simple type; genericizing an options base class so the option type becomes an unresolved type variable; arrays mistaken for an acceptable accumulation type.
Related errors
- Option that allows multiple occurrences must be assignable t
- Can't set an option to accumulate multiple values and let it
- Default values for multiple options are not allowed - use "n
- Option is an expansion flag with a static expansion, but doe
- Option that allows multiple occurrences must be of type %s,
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/966f5eec3a7e1377.
Report an issue: GitHub.