SonarSource/sonarqube · error · IllegalStateException

Error while executing GraphQl query. Return code %s. Error m

Error message

Error while executing GraphQl query. Return code %s. Error message: %s.

What it means

GraphQlClient.executeCallAndDeserializeAnswer checks the HTTP status of the OkHttp response before parsing. Any non-2xx status (401, 403, 404, 5xx...) aborts with an IllegalStateException carrying the return code and raw response body, since a GraphQL answer cannot be expected from a failed HTTP call.

Source

Thrown at server/sonar-server-common/src/main/java/org/sonar/server/common/graphql/GraphQlClient.java:134

  private <T> GsonGraphQlAnswer<T> fetchValidDataOrThrow(
    String graphQlApiUrl,
    String accessToken,
    Type answerDataType,
    GsonGraphQlQuery paginatedQuery
  ) throws IOException {
    RequestBody body = RequestBody.create(GSON.toJson(paginatedQuery), MediaType.parse("application/json; charset=utf-8"));
    Request request = new Request.Builder()
      .url(graphQlApiUrl)
      .post(body)
      .addHeader("Authorization", "Bearer " + accessToken)
      .build();
    return executeCallAndDeserializeAnswer(answerDataType, request);
  }

  private <T> @NotNull GsonGraphQlAnswer<T> executeCallAndDeserializeAnswer(Type answerDataType, Request request) throws IOException {
    try (Response response = client.newCall(request).execute()) {
      if (!response.isSuccessful()) {
        throw new IllegalStateException(format("Error while executing GraphQl query. Return code %s. Error message: %s.", response.code(), response.body().string()));
      }
      return deserializeValidAnswerOrThrow(answerDataType, response);
    }
  }

  private static <T> GsonGraphQlAnswer<T> deserializeValidAnswerOrThrow(Type answerDataType, Response response) {
    GsonGraphQlAnswer<T> graphQlAnswer;
    Function<String, GsonGraphQlAnswer<T>> toObject = stringPayload -> GSON.fromJson(stringPayload, answerDataType);
    Optional<String> bodyString = Optional.empty();
    try {
      bodyString = Optional.ofNullable(response.body()).map(body -> {
        try {
          return body.string();
        } catch (IOException e) {
          throw new IllegalStateException(e);
        }
      });
      graphQlAnswer = bodyString.map(toObject).orElseThrow();

View on GitHub (pinned to 184c821202)

Solutions

  1. Inspect the return code and error message embedded in the exception to identify the server-side cause.
  2. Verify the GraphQL endpoint URL and that the client targets the API path, not a UI page.
  3. Check/renew authentication credentials (token) if the code is 401/403.
  4. Check server health/status; retry with backoff for transient 5xx.
  5. Confirm network/proxy configuration allows reaching the host.

Example fix

// before
Request request = new Request.Builder().url("https://host/sonar").build();
// after
Request request = new Request.Builder()
  .url("https://host/sonar/api/graphql")
  .header("Authorization", "Bearer " + token)
  .build();
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight: check endpoint reachability
HttpRequest req = HttpRequest.newBuilder(URI.create(baseUrl + "/api/system/status")).GET().build();
// ensure 200 before issuing GraphQL queries

Try / catch

try {
  T data = graphQlClient.fetchValidDataOrThrow(...);
} catch (IllegalStateException e) {
  if (e.getMessage().contains("Return code 40") ) renewToken();
  else if (e.getMessage().contains("Return code 5")) retryWithBackoff();
  else throw e;
}

Prevention

When it happens

Trigger: Calling any GraphQlClient query (e.g. fetchValidDataOrThrow) against an endpoint returning 4xx/5xx: wrong base URL, expired/missing token, server outage, proxy errors, rate limiting.

Common situations: Expired API credentials returning 401; firewall/proxy intercepting with 403 or 502; the target service being down (503); pointing the client at a UI URL instead of the GraphQL endpoint (404).

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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