SonarSource/sonarqube · error · IllegalArgumentException
This WS is unsupported in commercial edition. Please…
Error message
This WS is unsupported in commercial edition. Please install plugin manually.
What it means
InstallAction only supports plugin installation on Community Edition. On any commercial edition (Developer, Enterprise, Data Center) plugins are shipped bundled with the edition, so calling api/plugins/install is rejected with this IllegalArgumentException in checkEdition, invoked at the start of handle.
Solutions
- Do not install plugins via this WS on commercial editions; install the matching SonarSource edition artifacts that bundle the plugin, per SonarSource upgrade docs.
- Gate the automation on edition: call api/system/status or server id/edition info first and skip plugin install for non-community editions.
- If a specific plugin is missing on the commercial edition, contact SonarSource support or use the edition-provided plugin set instead of manual installs.
Example fix
// before
await api.plugins.install({ key: 'sonar-java' });
// after
const edition = await getServerEdition();
if (edition === 'community') {
await api.plugins.install({ key: 'sonar-java' });
} // else plugin is bundled with the commercial edition
Defensive patterns
Strategy: validation
Validate before calling
const edition = await getServerEdition(); // from api/system/status or info
if (edition && edition !== 'community') {
throw new Error(`plugin install WS unsupported on ${edition}; use bundled edition plugins`);
} Type guard
function isCommunityEdition(edition) {
return typeof edition === 'string' && edition.toLowerCase() === 'community';
} Try / catch
try {
await api.plugins.install({ key });
} catch (e) {
if (String(e.message).includes('unsupported in commercial edition')) {
log('skip manual install; plugin ships with the edition');
return;
}
throw e;
} Prevention
- Detect edition before running marketplace automation and branch accordingly.
- After migrating off Community Edition, remove plugin-install steps from pipelines.
- Rely on edition-bundled plugins instead of manual installs on paid editions.
When it happens
Trigger: POST api/plugins/install?key=<key> on a commercial edition instance (editionProvider returns any edition other than COMMUNITY); typically automation scripts reused after an organization upgraded from Community Edition.
Common situations: CI pipelines or provisioning scripts that installed plugins on Community Edition breaking after migration to Developer/Enterprise Edition; operators expecting marketplace API parity across editions.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Can't install plugin without accepting firstly plugins risk…
- No plugin with key ' ' or plugin ' ' is already installed…
- No plugin with key ' ' or plugin ' ' is already in latest…
- Plugin not found
- SonarSource commercial plugin with key
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/2e63124ff9f79fdc.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstallAction.java:101
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkIsSystemAdministrator();
checkEdition();
if (!hasPluginInstallConsent()) {
throw new IllegalArgumentException("Can't install plugin without accepting firstly plugins risk consent");
}
String key = request.mandatoryParam(PARAM_KEY);
PluginUpdate pluginUpdate = findAvailablePluginByKey(key);
pluginDownloader.download(key, pluginUpdate.getRelease().getVersion());
response.noContent();
}
private void checkEdition() {
Edition edition = editionProvider.get().orElse(Edition.COMMUNITY);
if (!Edition.COMMUNITY.equals(edition)) {
throw new IllegalArgumentException("This WS is unsupported in commercial edition. Please install plugin manually.");
}
}
private boolean hasPluginInstallConsent() {
Optional<String> pluginRiskConsent = configuration.get(PLUGINS_RISK_CONSENT);
return pluginRiskConsent.filter(s -> PluginRiskConsent.valueOf(s) == PluginRiskConsent.ACCEPTED).isPresent();
}
private PluginUpdate findAvailablePluginByKey(String key) {
PluginUpdate pluginUpdate = null;
Optional<UpdateCenter> updateCenter = updateCenterFactory.getUpdateCenter(false);
if (updateCenter.isPresent()) {
pluginUpdate = updateCenter.get().findAvailablePlugins()
.stream()
.filter(Objects::nonNull)
.filter(u -> key.equals(u.getPlugin().getKey()))
.findFirst()View on GitHub (pinned to 184c821202)