{"record":{"id":"2534ea264475a97c","repo":"SonarSource/sonarqube","slug":"could-not-parse-gitlab-answer-to-retrieve-a-projec","errorCode":null,"errorMessage":"Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.","messagePattern":"Could not parse GitLab answer to retrieve a project\\. Got a non-json payload as result\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java","lineNumber":318,"sourceCode":"    }\n  }\n\n  public Project getProject(String gitlabUrl, String pat, Long gitlabProjectId) {\n    String url = format(\"%s/projects/%s\", gitlabUrl, gitlabProjectId);\n    LOG.debug(\"get project : [{}]\", url);\n    Request request = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, pat)\n      .get()\n      .url(url)\n      .build();\n\n    try (Response response = client.newCall(request).execute()) {\n      checkResponseIsSuccessful(response);\n      String body = response.body().string();\n      LOG.trace(\"loading project payload result : [{}]\", body);\n      return new GsonBuilder().create().fromJson(body, Project.class);\n    } catch (JsonSyntaxException e) {\n      throw new IllegalArgumentException(\"Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.\");\n    } catch (IOException e) {\n      logException(url, e);\n      throw new IllegalStateException(e.getMessage(), e);\n    }\n  }\n\n  //\n  // This method is used to check if a user has REPORTER level access to the project, which is a requirement for PR decoration.\n  // As of June 9, 2021 there is no better way to do this check and still support GitLab 11.7.\n  //\n  public Optional<Project> getReporterLevelAccessProject(String gitlabUrl, String pat, Long gitlabProjectId) {\n    String url = format(\"%s/projects?min_access_level=20&id_after=%s&id_before=%s\", gitlabUrl, gitlabProjectId - 1,\n      gitlabProjectId + 1);\n    LOG.debug(\"get project : [{}]\", url);\n    Request request = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, pat)\n      .get()\n      .url(url)","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java#L300-L336","documentation":"getProject fetches a single GitLab project via the GitLab API and deserializes the JSON body into a Project object with Gson. When the response body is not valid JSON, Gson throws JsonSyntaxException, which is rethrown as this IllegalArgumentException with the original parse exception swallowed. This means GitLab returned something unexpected (HTML error page, empty body, proxy page) instead of the expected project JSON.","triggerScenarios":"Calling getProject(url, token, projectIdentifier) when the GitLab HTTP response (already verified as a 2xx status by checkResponseIsSuccessful) contains a body that fails Gson parsing — e.g. an HTML page from a reverse proxy, an empty body, or a plain-text message instead of JSON.","commonSituations":"A reverse proxy or corporate gateway intercepts the request and returns an HTML 2xx page; the GitLab URL points at a non-API endpoint or wrong host; SSO/redirect middleware returns HTML; a misconfigured load balancer returns an empty body.","solutions":["Verify the configured GitLab URL is correct and points directly at the GitLab instance, not through a proxy that injects HTML.","Check the token: use a personal access token, not an OAuth redirect flow that might yield an HTML login page.","Inspect network path (VPN, corporate proxy, SSO) for components that return HTML with 2xx status codes.","Enable trace logging (loading project payload result) to capture the actual body and diagnose what GitLab returned."],"exampleFix":"// before: swallowed JsonSyntaxException hides the cause\nthrow new IllegalArgumentException(\"Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.\");\n// after: log the body first, as done at trace level, to see what came back\nLOG.trace(\"loading project payload result : [{}]\", body);\nreturn new GsonBuilder().create().fromJson(body, Project.class);","handlingStrategy":"try-catch","validationCode":"if (gitlabUrl == null || !gitlabUrl.startsWith(\"http\")) throw new IllegalArgumentException(\"GitLab URL must be configured\");","typeGuard":null,"tryCatchPattern":"try { project = gitlabClient.getProject(url, token, repo); } catch (IllegalArgumentException e) { LOG.error(\"GitLab returned non-JSON payload; check URL/proxy config\", e); }","preventionTips":["Point the GitLab URL directly at the instance, avoiding HTML-injecting proxies","Verify connectivity with curl before saving the configuration","Enable trace logging to capture raw payloads when diagnosing"],"tags":["gitlab","json-parsing","http-response","devops-integration"],"backgroundTag":"invalid-json-response","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"}