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
- Give each annotated method a distinct Starlark name (@StarlarkMethod(name = ...)).
- Remove the annotation from the method that should not be Starlark-visible.
- Rename or delete the redundant Java overload.
- 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
- Use distinct @StarlarkMethod(name=...) values for every exposed method in a hierarchy.
- Avoid copy-pasting annotations when adding convenience methods.
- Test that a class's full descriptor builds without exceptions.
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
- Class %s has an incompatible overload of annotated method %s
- Expected one of %s and %s to be a subclass of the other
- Class %s has two selfCall methods defined
- Converter %s has %d methods 'convert(String, Object)', expec
- %s missing getStarlarkType(StarlarkSemantics) method
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/13c16f97aa466928.
Report an issue: GitHub.