SonarSource/sonarqube · error · IllegalArgumentException
No plugin with key ' ' or plugin ' ' is already installed…
Error message
No plugin with key '%s' or plugin '%s' is already installed in latest version
What it means
After edition and consent checks, InstallAction resolves the requested key against available plugin updates from the update center (new plugins plus already-installed plugins whose latest version differs from the installed one). If no PluginUpdate matches the key, it throws IllegalArgumentException stating the plugin does not exist or is already at its latest version.
Solutions
- Check GET api/plugins/available to confirm the exact key exists and is not already installed in the latest version; skip the call if so.
- Make installation idempotent: query api/plugins/installed first and only call install when a newer version is offered.
- Ensure sonar.updatecenter.url is reachable (proxy/firewall) so the update center list is populated; then retry.
Example fix
// before
await api.plugins.install({ key: 'sonar-python' }); // fails when already latest
// after
const available = await api.plugins.available();
if (available.plugins.some(p => p.key === 'sonar-python')) {
await api.plugins.install({ key: 'sonar-python' });
} Defensive patterns
Strategy: validation
Validate before calling
const available = (await api.plugins.available()).plugins;
const installed = (await api.plugins.installed()).plugins;
const canInstall = available.some(p => p.key === key) && !atLatestVersion(installed, key);
if (!canInstall) throw new Error(`nothing to install for key '${key}'`); Type guard
function canInstall(available, installed, key) {
return available.some(p => p.key === key) &&
!(installed.some(p => p.key === key) && updateCenterHasNoNewer(key));
} Try / catch
try {
await api.plugins.install({ key });
} catch (e) {
if (String(e.message).startsWith('No plugin with key')) {
log(`skipping '${key}': unknown or already at latest version`);
return;
}
throw e;
} Prevention
- Make install scripts idempotent by checking installed/available state first.
- Verify exact plugin keys from the marketplace API, not plugin names.
- Ensure the update center is reachable so the available list is populated.
When it happens
Trigger: POST api/plugins/install?key=<key> where the key matches no update-center entry: unknown key, typo, plugin already installed at the newest compatible version, or update center not yet populated/synced.
Common situations: Scripts installing a plugin that is already up to date (idempotent re-runs); key mismatch between marketplace name and plugin key; update center blocked by a proxy so the available-plugin list is empty.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Can't install plugin without accepting firstly plugins risk…
- No plugin with key ' ' or plugin ' ' is already in latest…
- Plugin not found
- SonarSource commercial plugin with key
- This WS is unsupported in commercial edition. Please…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/f46c8c49b179679c.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstallAction.java:124
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()
.orElse(null);
}
if (pluginUpdate == null) {
throw new IllegalArgumentException(
format("No plugin with key '%s' or plugin '%s' is already installed in latest version", key, key));
}
if (isEditionBundled(pluginUpdate.getPlugin())) {
throw new IllegalArgumentException(format(
"SonarSource commercial plugin with key '%s' can only be installed as part of a SonarSource edition",
pluginUpdate.getPlugin().getKey()));
}
return pluginUpdate;
}
}
View on GitHub (pinned to 184c821202)