bazelbuild/bazel · error · IllegalStateException

Class %s has multiple overloaded methods named '%s' annotate

Error message

Class %s has multiple overloaded methods named '%s' annotated with @StarlarkMethod

What it means

Starlark methods are dispatched by name only, so a Java class may expose at most one @StarlarkMethod-annotated method per name. If reflection finds a second annotated method with the same name (across the class and its supertypes), this IllegalStateException is thrown while building the class descriptor. Note Java overloading itself is legal; the restriction is on annotating both overloads.

Source

Thrown at src/main/java/net/starlark/java/annot/StarlarkAnnotations.java:235

        Class<?>[] paramTypes = method.getParameterTypes();

        if (paramTypes.length == paramsToMatch.length) {
          for (int i = 0; i < paramTypes.length; i++) {
            // This verifies assignability of the method signature to ensure this is not a
            // coincidental overload. We verify assignability instead of matching exact parameter
            // classes in order to match generic methods.
            if (!paramTypes[i].isAssignableFrom(paramsToMatch[i])) {
              throw new IllegalStateException(
                  String.format(
                      "Class %s has an incompatible overload of annotated method %s declared by %s",
                      classObj, signatureToMatch.getName(), signatureToMatch.getDeclaringClass()));
            }
          }
        }
        if (callable == null) {
          callable = method.getAnnotation(StarlarkMethod.class);
        } else {
          throw new IllegalStateException(
              String.format(
                  "Class %s has multiple overloaded methods named '%s' annotated "
                      + "with @StarlarkMethod",
                  classObj, signatureToMatch.getName()));
        }
      }
    }
    return callable;
  }

  private StarlarkAnnotations() {}
}

View on GitHub (pinned to e6e199d060)

Solutions

  1. Give each annotated method a distinct Starlark name (@StarlarkMethod(name = ...)).
  2. Remove the annotation from the method that should not be Starlark-visible.
  3. Rename or delete the redundant Java overload.
  4. If overriding, keep @StarlarkMethod only on the base declaration.

Example fix

// before
class M {
  @StarlarkMethod(name="items") public Sequence<?> items() {...}
  @StarlarkMethod(name="items") public Sequence<?> items(int n) {...}
}

// after
class M {
  @StarlarkMethod(name="items") public Sequence<?> items() {...}
  @StarlarkMethod(name="take") public Sequence<?> items(int n) {...}
}
Defensive patterns

Strategy: validation

Validate before calling

// Assert at most one annotated method per Starlark name on a class
static void checkUniqueNames(Class<?> c) {
  Set<String> seen = new HashSet<>();
  for (Class<?> k = c; k != null; k = k.getSuperclass()) {
    for (Method m : k.getDeclaredMethods()) {
      StarlarkMethod a = m.getAnnotation(StarlarkMethod.class);
      if (a == null) continue;
      if (!seen.add(a.name())) throw new AssertionError("duplicate Starlark name " + a.name() + " on " + c);
    }
  }
}

Prevention

When it happens

Trigger: Two @StarlarkMethod-annotated methods with the same name (same Starlark name attribute counts too) found on a class or inherited from interfaces/superclasses; one declared locally, one inherited annotated.

Common situations: Copy-pasting an annotated method into a subclass; two interfaces implemented by a class both annotating a method of the same name; renaming the Starlark-side name= of two methods to collide.

Related errors


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