{"record":{"id":"672d94ea24373886","repo":"SonarSource/sonarqube","slug":"error-while-deserializing-graphql-payload-s-s","errorCode":null,"errorMessage":"Error while deserializing GraphQL payload: %s. %s","messagePattern":"Error while deserializing GraphQL payload: (.+?)\\. (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/sonar-server-common/src/main/java/org/sonar/server/common/graphql/GraphQlClient.java","lineNumber":154,"sourceCode":"      return deserializeValidAnswerOrThrow(answerDataType, response);\n    }\n  }\n\n  private static <T> GsonGraphQlAnswer<T> deserializeValidAnswerOrThrow(Type answerDataType, Response response) {\n    GsonGraphQlAnswer<T> graphQlAnswer;\n    Function<String, GsonGraphQlAnswer<T>> toObject = stringPayload -> GSON.fromJson(stringPayload, answerDataType);\n    Optional<String> bodyString = Optional.empty();\n    try {\n      bodyString = Optional.ofNullable(response.body()).map(body -> {\n        try {\n          return body.string();\n        } catch (IOException e) {\n          throw new IllegalStateException(e);\n        }\n      });\n      graphQlAnswer = bodyString.map(toObject).orElseThrow();\n    } catch (Exception exception) {\n      throw new IllegalStateException(format(\"Error while deserializing GraphQL payload: %s. %s\", exception.getMessage(), bodyString), exception);\n    }\n    if (!graphQlAnswer.isValid()) {\n      throw new IllegalStateException(\"The GraphQl answer contains errors: \" + graphQlAnswer.errors());\n    }\n    return graphQlAnswer;\n  }\n\n}\n","sourceCodeStart":136,"sourceCodeEnd":163,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-server-common/src/main/java/org/sonar/server/common/graphql/GraphQlClient.java#L136-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nRequest request = new Request.Builder().url(baseUrl).build();\n// after\nRequest request = new Request.Builder()\n  .url(baseUrl + \"/api/graphql\")\n  .header(\"Authorization\", \"Bearer \" + token)\n  .build();","handlingStrategy":"try-catch","validationCode":"// Verify the endpoint returns JSON, not an HTML page, before parsing:\n// curl -H \"Authorization: Bearer $TOKEN\" -H \"Accept: application/json\" $BASE/api/graphql","typeGuard":null,"tryCatchPattern":"try {\n  return graphQlClient.fetchValidDataOrThrow(type, request);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"<html\")) throw new AuthenticationException(\"Intercepted by login/error page\");\n  throw e;\n}","preventionTips":["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."],"tags":["graphql","deserialization","json"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}