SonarSource/sonarqube · error · IllegalArgumentException

Could not parse GitLab answer to search projects. Got a non-

Error message

Could not parse GitLab answer to search projects. Got a non-json payload as result.

What it means

searchProjects queries the GitLab projects search endpoint, reads pagination headers (X-Page, X-Per-Page, X-Total) and parses the JSON project list. If the body fails Gson parsing, JsonSyntaxException is rethrown as this IllegalArgumentException. GitLab answered successfully but with a payload that is not the expected JSON array.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:406

    LOG.debug("get projects : [{}]", url);
    Request request = new Request.Builder()
      .addHeader(PRIVATE_TOKEN, personalAccessToken)
      .url(url)
      .get()
      .build();

    try (Response response = client.newCall(request).execute()) {
      Headers headers = response.headers();
      checkResponseIsSuccessful(response, "Could not get projects from GitLab instance");
      List<Project> projectList = Project.parseJsonArray(response.body().string());
      int returnedPageNumber = parseAndGetIntegerHeader(headers.get("X-Page"));
      int returnedPageSize = parseAndGetIntegerHeader(headers.get("X-Per-Page"));
      String xtotal = headers.get("X-Total");
      Integer totalProjects = Strings.isEmpty(xtotal) ? null : parseAndGetIntegerHeader(xtotal);
      return new ProjectList(projectList, returnedPageNumber, returnedPageSize, totalProjects);
    } catch (JsonSyntaxException e) {
      throw new IllegalArgumentException("Could not parse GitLab answer to search projects. Got a non-json payload as result.");
    } catch (IOException e) {
      logException(url, e);
      throw new IllegalStateException(e.getMessage(), e);
    }
  }

  private static int parseAndGetIntegerHeader(@Nullable String header) {
    if (header == null) {
      throw new IllegalArgumentException("Pagination data from GitLab response is missing");
    } else {
      try {
        return Integer.parseInt(header);
      } catch (NumberFormatException e) {
        throw new IllegalArgumentException("Could not parse pagination number", e);
      }
    }
  }

View on GitHub (pinned to 184c821202)

Solutions

  1. Validate the GitLab URL configuration reaches the GitLab API directly.
  2. Trace-log the body (payload result) to identify what non-JSON content was returned.
  3. Check intermediate proxies/load balancers for HTML injection into 2xx responses.
  4. Retry the search; if intermittent, investigate GitLab instance health or rate-limiting intermediaries.
Defensive patterns

Strategy: retry

Try / catch

try { ProjectList list = client.searchProjects(url, token, query, page, size); } catch (IllegalArgumentException e) { /* retry once, then report config/network issue */ }

Prevention

When it happens

Trigger: Calling searchProjects(url, token, ...) (also exercised by fetchTotalCount) when the 2xx response body is HTML, empty, or otherwise non-JSON while paging through GitLab projects.

Common situations: Corporate proxy or SSO intercepts paginated project list requests and returns HTML; wrong GitLab URL; load balancer timeouts returning empty 200 bodies; GitLab maintenance pages served with success status.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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