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

  1. Make the converter implement com.google.devtools.common.options.Converter and override exactly one public convert(String input, Object context) method.
  2. Remove or rename any extra overloads whose signature is (String, Object).
  3. 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

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


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