SonarSource/sonarqube · error · IllegalArgumentException

Unsupported implementation: %s

Error message

Unsupported implementation: %s

What it means

HttpConnector.call() dispatches an httpRequest to executeRequest() based on whether it implements RequestWithoutPayload or RequestWithPayload. If the request object implements neither, it throws IllegalArgumentException("Unsupported implementation: <class>"). This is an internal dispatch guard — it means a request type unknown to this connector version was passed in.

Source

Thrown at sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java:124

  @Override
  public String baseUrl() {
    return baseUrl.url().toExternalForm();
  }

  public OkHttpClient okHttpClient() {
    return okHttpClient;
  }

  @Override
  public WsResponse call(WsRequest httpRequest) {
    if (httpRequest instanceof RequestWithoutPayload httpRequestWithoutPayload) {
      return executeRequest(httpRequestWithoutPayload);
    }
    if (httpRequest instanceof RequestWithPayload httpRequestWithPayload) {
      return executeRequest(httpRequestWithPayload);
    }
    throw new IllegalArgumentException(format("Unsupported implementation: %s", httpRequest.getClass()));
  }

  private WsResponse executeRequest(RequestWithoutPayload<?> request) {
    HttpUrl.Builder urlBuilder = prepareUrlBuilder(request);
    completeUrlQueryParameters(request, urlBuilder);

    Request.Builder okRequestBuilder = prepareOkRequestBuilder(request, urlBuilder);
    okRequestBuilder = request.addVerbToBuilder().apply(okRequestBuilder);
    return new OkHttpResponse(doCall(prepareOkHttpClient(okHttpClient, request), okRequestBuilder.build()));
  }

  private WsResponse executeRequest(RequestWithPayload<?> request) {
    HttpUrl.Builder urlBuilder = prepareUrlBuilder(request);

    RequestBody body;
    Map<String, Part> parts = request.getParts();
    if (request.hasBody()) {
      MediaType contentType = MediaType.parse(request.getContentType().orElse(JSON));

View on GitHub (pinned to 184c821202)

Solutions

  1. Use the request types built by the same sonar-ws version as the connector (GetRequest/PostRequest from org.sonarqube.ws.client).
  2. Run mvn dependency:tree and exclude duplicate/conflicting sonar-ws-client versions.
  3. Rebuild/re-shade after upgrading SonarQube dependencies so request and connector classes come from the same jar.
  4. If implementing a custom request type, make it implement RequestWithoutPayload or RequestWithPayload.

Example fix

// before
MyCustomRequest req = new MyCustomRequest("api/issues/search");
wsConnector.call(req);
// after
GetRequest req = new GetRequest("api/issues/search").setParam("components", "my_project");
wsConnector.call(req);
Defensive patterns

Strategy: validation

Validate before calling

if (!(httpRequest instanceof RequestWithoutPayload) && !(httpRequest instanceof RequestWithPayload)) {
  throw new IllegalArgumentException("Use GetRequest or PostRequest from the same sonar-ws version");
}

Type guard

static boolean isSupportedRequest(Object r) {
  return r instanceof RequestWithoutPayload || r instanceof RequestWithPayload;
}

Prevention

When it happens

Trigger: Passing a custom/legacy GetRequest/PostRequest-like object that implements neither RequestWithoutPayload nor RequestWithPayload marker interfaces; usually caused by mixing sonar-ws-client versions on the classpath or passing an object from a different library.

Common situations: Classpath conflicts with multiple sonar-ws versions (e.g. from a shaded dependency or older sonarqube-ws client); upgrading SonarQube client libraries without rebuilding; passing a hand-rolled request implementation.

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


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/c0229b3e70be332f. Report an issue: GitHub.