bazelbuild/bazel · error · OptionProcessorException
Converter %s has %d methods 'convert(String, Object)', expec
Error message
Converter %s has %d methods 'convert(String, Object)', expected 1: %s
What it means
Bazel's options annotation processor requires that a supplied converter class expose exactly one method named convert taking exactly (String, Object). This error fires when zero or multiple matching overloads are found — the processor could not unambiguously locate the conversion entry point.
Source
Thrown at src/main/java/com/google/devtools/common/options/processor/OptionsClassProcessor.java:680
DeclaredType converterType = (DeclaredType) converterElement.asType();
List<ExecutableElement> methodList =
elementUtils.getAllMembers(converterElement).stream()
.filter(element -> element.getKind() == ElementKind.METHOD)
.map(methodElement -> (ExecutableElement) methodElement)
.filter(methodElement -> methodElement.getSimpleName().contentEquals("convert"))
.filter(
methodElement ->
methodElement.getParameters().size() == 2
&& typeUtils.isSameType(
methodElement.getParameters().get(0).asType(),
elementUtils.getTypeElement(String.class.getCanonicalName()).asType())
&& typeUtils.isSameType(
methodElement.getParameters().get(1).asType(),
elementUtils.getTypeElement(Object.class.getCanonicalName()).asType()))
.collect(Collectors.toList());
if (methodList.size() != 1) {
throw new OptionProcessorException(
method,
"Converter %s has %d methods 'convert(String, Object)', expected 1: %s",
converterElement,
methodList.size(),
methodList.stream().map(Object::toString).collect(Collectors.joining(", ")));
}
ExecutableType convertMethodType =
(ExecutableType) typeUtils.asMemberOf(converterType, methodList.get(0));
TypeMirror convertMethodResultType = convertMethodType.getReturnType();
for (TypeMirror acceptedConverterReturnType : acceptedConverterReturnTypes) {
if (typeUtils.isAssignable(convertMethodResultType, acceptedConverterReturnType)) {
return;
}
}
throw new OptionProcessorException(
method,
"Type of field (%s) must be assignable from the converter's return type (%s)",View on GitHub (pinned to e6e199d060)
Solutions
- Make the converter implement com.google.devtools.common.options.Converter and override exactly one public convert(String input, Object context) method.
- Remove or rename any extra overloads whose signature is (String, Object).
- Check that visibility is public and the class is concrete; recompile and inspect the error message, which lists the candidate methods it found.
Example fix
// before
class ModeConverter implements Converter<String> {
public String convert(String input) { ... } // wrong arity
}
// after
class ModeConverter implements Converter<String> {
@Override
public String convert(String input, Object ignored) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
static void assertSingleConvertMethod(Class<?> converter) {
long matches = Arrays.stream(converter.getMethods())
.filter(m -> m.getName().equals("convert"))
.filter(m -> m.getParameterCount() == 2)
.filter(m -> m.getParameterTypes()[0] == String.class
&& m.getParameterTypes()[1] == Object.class)
.count();
Preconditions.checkState(matches == 1,
"Converter %s must have exactly one convert(String, Object) method, found %d",
converter.getName(), matches);
} Prevention
- Always implement com.google.devtools.common.options.Converter and use @Override on convert(String, Object) so signature mistakes fail fast.
- Do not add (String, Object) overloads of convert; give helpers different names.
When it happens
Trigger: A converter class that lacks a public convert(String, Object) method (wrong parameter types, single-argument convert(String), or the method lives only in a sibling class), or that declares several 2-arg overloads of convert with first param String and second param Object (e.g. via overloaded signatures in generic hierarchies).
Common situations: Implementing the Converter interface incorrectly (custom convert(String) instead of the interface's convert(String, Object)); adding convenience overloads that also match the (String, Object) shape; bridging/inheritance producing duplicate resolved signatures; forgetting to implement the interface at all and relying on a differently-named method.
Related errors
- Option lists a default value (%s) that is not parsable by th
- Cannot find valid converter for option of type %s
- The converter type %s must be a concrete type
- Type of field (%s) must be assignable from the converter's r
- Option includes UNKNOWN with other, known, effects. Please r
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/e213b34959e30537.
Report an issue: GitHub.