SonarSource/sonarqube · error · IllegalStateException
Modules should be added as instances
Error message
Modules should be added as instances
What it means
SpringComponentContainer.add() throws this IllegalStateException when a Module is passed as a Class instead of an instance. Modules must be configured (module.configure(this) is invoked on instances); registering a Module class as a bean type would skip configuration and silently register it as a component instead, so the container rejects the pattern outright.
Source
Thrown at sonar-core/src/main/java/org/sonar/core/platform/SpringComponentContainer.java:102
add(new StartableBeanPostProcessor());
add(externalExtensions);
add(propertyDefs);
}
/**
* Beans need to have a unique name, otherwise they'll override each other.
* The strategy is:
* - For classes, use the classloader + fully qualified class name as the name of the bean
* - For instances, use the Classloader + FQCN + toString()
* - If the object is a collection, iterate through the elements and apply the same strategy for each of them
*/
@Override
public Container add(Object... objects) {
for (Object o : objects) {
if (o instanceof Class) {
Class<?> clazz = (Class<?>) o;
if (Module.class.isAssignableFrom(clazz)) {
throw new IllegalStateException("Modules should be added as instances");
}
context.registerBean(componentKeys.ofClass(clazz), clazz);
declareExtension("", o);
} else if (o instanceof Module module) {
module.configure(this);
} else if (o instanceof Iterable) {
add(Iterables.toArray((Iterable<?>) o, Object.class));
} else {
registerInstance(o);
declareExtension("", o);
}
}
return this;
}
@Override
public void addWebApiV2ConfigurationClass(Class<?> clazz) {
webConfigurationClasses.add(clazz);View on GitHub (pinned to 184c821202)
Solutions
- Pass a Module instance instead of the class: container.add(new MyModule()).
- Only pass Class objects for components that are not Modules (beans to be instantiated by the container).
- If the class genuinely should not be a Module, remove the 'implements Module' declaration.
Example fix
// before container.add(CoreModule.class); // after container.add(new CoreModule());
Defensive patterns
Strategy: type-guard
Validate before calling
void safeAdd(SpringComponentContainer container, Object... objects) {
for (Object o : objects) {
if (o instanceof Class<?> clazz && Module.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Pass Module instances, not classes: " + clazz.getName());
}
}
container.add(objects);
} Type guard
boolean isModuleClass(Object o) {
return o instanceof Class<?> clazz && Module.class.isAssignableFrom(clazz); // never pass these to add()
} Try / catch
try {
container.add(x);
} catch (IllegalStateException e) {
// 'Modules should be added as instances': replace x with new X()
} Prevention
- Always instantiate Modules with new: container.add(new MyModule()).
- Reserve Class arguments for bean components only.
- Review add() call sites when introducing new Module subclasses.
When it happens
Trigger: Calling container.add(SomeModule.class) where SomeModule implements Module (directly or via subclass) — the Class branch detects Module.class.isAssignableFrom(clazz) and throws.
Common situations: Copy-pasting a component registration line and accidentally passing a Module subclass's class literal instead of 'new SomeModule()'; switching from add(new X()) to add(X.class) for a Module.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/4b6b4a9b9c32ecb9.
Report an issue: GitHub.