SonarSource/sonarqube · error · UnsupportedOperationException
Can only be called in SonarQube
Error message
Can only be called in SonarQube
What it means
SonarRuntimeImpl.getSonarQubeSide() returns the SonarQube side (scanner vs compute engine vs web server) only when the runtime was created for a SonarQube environment. When the runtime has no side (e.g. built for SonarLint/standalone, where sonarQubeSide is null) it throws UnsupportedOperationException with "Can only be called in SonarQube". The library throws this because 'side' is meaningless outside SonarQube.
Source
Thrown at sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java:67
this.apiVersion = requireNonNull(apiVersion);
this.product = product;
this.sonarQubeSide = sonarQubeSide;
}
@Override
public Version getApiVersion() {
return apiVersion;
}
@Override
public SonarProduct getProduct() {
return product;
}
@Override
public SonarQubeSide getSonarQubeSide() {
if (sonarQubeSide == null) {
throw new UnsupportedOperationException("Can only be called in SonarQube");
}
return sonarQubeSide;
}
@Override
public SonarEdition getEdition() {
if (sonarQubeSide == null) {
throw new UnsupportedOperationException("Can only be called in SonarQube");
}
return edition;
}
/**
* Create an instance for SonarQube runtime environment.
*/
public static SonarRuntime forSonarQube(Version apiVersion, SonarQubeSide side, SonarEdition edition) {
return new SonarRuntimeImpl(apiVersion, SonarProduct.SONARQUBE, side, edition);
}View on GitHub (pinned to 184c821202)
Solutions
- Guard the call: only invoke getSonarQubeSide() when runtime.getProduct() == SonarProduct.SONARQUBE.
- Branch on getProduct() and provide a fallback for SonarLint execution.
- If the runtime should be SonarQube, construct it with SonarRuntimeImpl.forSonarQube(...) passing a valid SonarQubeSide.
Example fix
// before
SonarQubeSide side = runtime.getSonarQubeSide();
// after
if (runtime.getProduct() == SonarProduct.SONARQUBE) {
SonarQubeSide side = runtime.getSonarQubeSide();
} else {
// SonarLint path: no side concept
} Defensive patterns
Strategy: type-guard
Validate before calling
// Java boolean sideAvailable = runtime.getProduct() == SonarProduct.SONARQUBE;
Type guard
// Java
static boolean hasSonarQubeSide(SonarRuntime runtime) {
return runtime.getProduct() == SonarProduct.SONARQUBE;
} Try / catch
// Java
try {
SonarQubeSide side = runtime.getSonarQubeSide();
} catch (UnsupportedOperationException e) {
// SonarLint / standalone path
} Prevention
- Always branch on runtime.getProduct() before using side/edition APIs.
- Write plugin code paths that work identically in SonarLint.
- Use SonarRuntimeImpl.forSonarQube only when the process actually runs inside SonarQube.
When it happens
Trigger: Calling runtime.getSonarQubeSide() on a runtime created via SonarRuntimeImpl.forSonarLint(...) (or an equivalent standalone runtime) where sonarQubeSide is null.
Common situations: Plugin or analyzer code shared between SonarLint and SonarQube calling getSonarQubeSide() unconditionally while running inside the SonarLint IDE integration.
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
- Cannot resolve issue at line {} of {} due to: {}
- Github configuration is not complete. Please check your conf
- Configuration is not complete : %s
- LDAP realm failed to start:
- Analysis report %s part %s is missing in database
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/704503fca4e24983.
Report an issue: GitHub.