SonarSource/sonarqube · error · IllegalStateException
Error while deserializing GraphQL payload: %s. %s
Error message
Error while deserializing GraphQL payload: %s. %s
What it means
After a successful HTTP call, deserializeValidAnswerOrThrow parses the response body into a typed GsonGraphQlAnswer. Any exception during body reading or Gson deserialization (malformed JSON, HTML error page, unexpected payload shape) is wrapped in an IllegalStateException whose message includes the original exception text and the raw body for diagnosis.
Source
Thrown at server/sonar-server-common/src/main/java/org/sonar/server/common/graphql/GraphQlClient.java:154
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();
} catch (Exception exception) {
throw new IllegalStateException(format("Error while deserializing GraphQL payload: %s. %s", exception.getMessage(), bodyString), exception);
}
if (!graphQlAnswer.isValid()) {
throw new IllegalStateException("The GraphQl answer contains errors: " + graphQlAnswer.errors());
}
return graphQlAnswer;
}
}
View on GitHub (pinned to 184c821202)
Solutions
- Inspect the raw body embedded in the exception message — if it is HTML, the request is being intercepted (login page, error page).
- Verify authentication so the request reaches the actual GraphQL endpoint.
- Check that the expected answer type still matches the server's GraphQL schema (upgrade client types after server upgrades).
- Test the same query manually (curl) to compare the payload.
- Check for proxy/CDN interference altering the response.
Example fix
// before
Request request = new Request.Builder().url(baseUrl).build();
// after
Request request = new Request.Builder()
.url(baseUrl + "/api/graphql")
.header("Authorization", "Bearer " + token)
.build(); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the endpoint returns JSON, not an HTML page, before parsing: // curl -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" $BASE/api/graphql
Try / catch
try {
return graphQlClient.fetchValidDataOrThrow(type, request);
} catch (IllegalStateException e) {
if (e.getMessage().contains("<html")) throw new AuthenticationException("Intercepted by login/error page");
throw e;
} Prevention
- Always send authentication headers so proxies don't return HTML pages.
- Pin/upgrade client types with server schema versions.
- Set Accept: application/json on requests.
- Log the raw body included in the message when diagnosing.
When it happens
Trigger: The GraphQL endpoint returns a 2xx response whose body is not a valid JSON GraphQL answer: proxy or auth pages returning HTML with 200, truncated responses, or a schema/type change making the declared answer type unparseable.
Common situations: Reverse proxies or SSO redirects serving HTML login pages with status 200; API version drift after a server upgrade; gzip/encoding misconfiguration; network middleware corrupting the body.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Response from Azure for request [%s] could not be parsed: [%
- Unexpected response from Bitbucket server
- Could not parse GitLab answer to verify read permission. Got
- Could not parse GitLab answer to verify token. Got a non-jso
- Could not parse GitLab answer to verify token scopes. Got a
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/672d94ea24373886.
Report an issue: GitHub.