jenkinsci/jenkins · error · IllegalStateException
Expected 1 instance of ${type.getName()} but got ${all.size(
Error message
Expected 1 instance of ${type.getName()} but got ${all.size()} What it means
Thrown by ExtensionList.lookupSingleton when more than one instance of the requested type is registered. lookupSingleton demands exactly one; in unit-test mode an empty list gives a different message, but any count other than 1 (including 0 in non-test mode) hits this branch. This guards callers that cannot disambiguate duplicates.
Source
Thrown at core/src/main/java/hudson/ExtensionList.java:458
/**
* Convenience method allowing lookup of the only instance of a given type.
* Equivalent to {@code ExtensionList.lookup(Class).get(Class)} if there is one instance,
* and throws an {@code IllegalStateException} otherwise.
*
* @param type The type to look up.
* @return the singleton instance of the given type in its list.
* @throws IllegalStateException if there are no instances, or more than one
*
* @since 2.87
*/
public static @NonNull <U> U lookupSingleton(Class<U> type) {
ExtensionList<U> all = lookup(type);
if (Main.isUnitTest && all.isEmpty()) {
throw new IllegalStateException("Found no instances of " + type.getName() +
" registered (possible annotation processor issue); try using `mvn clean test -Dtest=…` rather than an IDE test runner");
} else if (all.size() != 1) {
throw new IllegalStateException("Expected 1 instance of " + type.getName() + " but got " + all.size());
}
return all.getFirst();
}
/**
* Convenience method allowing lookup of the instance of a given type with the highest ordinal.
* Equivalent to {@code ExtensionList.lookup(type).get(0)} if there is at least one instance,
* and throws an {@link IllegalStateException} otherwise if no instance could be found.
*
* @param type The type to look up.
* @return the singleton instance of the given type in its list.
* @throws IllegalStateException if there are no instances
*
* @since 2.435
*/
public static @NonNull <U> U lookupFirst(Class<U> type) {
var all = lookup(type);
if (!all.isEmpty()) {View on GitHub (pinned to 2e228ff40b)
Solutions
- Find and remove the duplicate @Extension registration (check the message's count and inspect manage/extensions).
- If duplicates are legitimate, use lookupFirst instead to pick the highest-ordinal instance.
- Adjust @Extension ordinal to make one registration win and the other effectively shadowed (still counted, so prefer removal).
- In tests, ensure only one instance is registered; reset the ExtensionList between tests.
Example fix
// before var s = ExtensionList.lookupSingleton(MyService.class); // 2 registered // after var s = ExtensionList.lookupFirst(MyService.class); // accepts duplicates, picks top
Defensive patterns
Strategy: validation
Validate before calling
ExtensionList<MyService> all = ExtensionList.lookup(MyService.class);
if (all.size() != 1) {
// duplicates or none — decide policy before calling lookupSingleton
} Type guard
static boolean isSingletonRegistered(Class<?> type) {
return ExtensionList.lookup(type).size() == 1;
} Try / catch
try {
var s = ExtensionList.lookupSingleton(MyService.class);
} catch (IllegalStateException e) {
// 'Expected 1 instance ... but got N' — use lookupFirst or remove the duplicate
var s = ExtensionList.lookupFirst(MyService.class);
} Prevention
- Avoid registering the same extension point from two plugins.
- In tests, reset the ExtensionList or use a single registration.
- Audit manage/extensions after plugin installs to catch duplicates early.
When it happens
Trigger: Two @Extension classes (or two registrations) of the same type are both loaded; a test registers a mock plus the real one; a plugin and core both register the same extension point; duplicate registrations from a fat jar.
Common situations: Plugin provides an extension point already provided by core or another installed plugin; test harness adds a duplicate; split-package issue loading the same class twice.
Related errors
- The class ${type.getName()} was not found, potentially not y
- Found no instances of ${type.getName()} registered
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/7d4f145eb46de77b.
Report an issue: GitHub.