SonarSource/sonarqube · error · IllegalArgumentException

Pull request with key '{}' does not target branch '{}'

Error message

Pull request with key '{}' does not target branch '{}'

What it means

In getIssuesFixedByPullRequest, when a branch param is supplied, the code verifies the pull request actually targets that branch by comparing the target branch UUID with the PR's mergeBranchUuid. A mismatch throws IllegalArgumentException 'Pull request with key X does not target branch Y'.

Source

Thrown at server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java:226

    checkArgument(StringUtils.isNotBlank(fixedInPullRequest), "Parameter '%s' is empty", PARAM_FIXED_IN_PULL_REQUEST);
    List<String> componentKeys = request.getComponentKeys();
    if (componentKeys == null || componentKeys.size() != 1) {
      throw new IllegalArgumentException("Exactly one project needs to be provided in the " +
        "'" + PARAM_COMPONENTS + "' param when used together with '" + PARAM_FIXED_IN_PULL_REQUEST + "' param");
    }
    String projectKey = componentKeys.get(0);
    ProjectDto projectDto = dbClient.projectDao().selectProjectByKey(dbSession, projectKey)
      .orElseThrow(() -> new IllegalArgumentException("Project with key '" + projectKey + "' does not exist"));
    BranchDto pullRequest = dbClient.branchDao().selectByPullRequestKey(dbSession, projectDto.getUuid(), fixedInPullRequest)
      .orElseThrow(() -> new IllegalArgumentException("Pull request with key '" + fixedInPullRequest + "' does not exist for project " +
        projectKey));

    String branch = request.getBranch();
    if (branch != null) {
      BranchDto targetBranch = dbClient.branchDao().selectByBranchKey(dbSession, projectDto.getUuid(), branch)
        .orElseThrow(() -> new IllegalArgumentException("Branch with key '" + branch + "' does not exist"));
      if (!Objects.equals(targetBranch.getUuid(), pullRequest.getMergeBranchUuid())) {
        throw new IllegalArgumentException("Pull request with key '" + fixedInPullRequest + "' does not target branch '" + branch + "'");
      }
    }
    return dbClient.issueFixedDao().selectByPullRequest(dbSession, pullRequest.getUuid())
      .stream()
      .map(IssueFixedDto::issueKey)
      .collect(Collectors.toSet());
  }

  private static Optional<ZoneId> parseTimeZone(@Nullable String timeZone) {
    if (timeZone == null) {
      return Optional.empty();
    }
    try {
      return Optional.of(ZoneId.of(timeZone));
    } catch (DateTimeException e) {
      LOGGER.warn("TimeZone '" + timeZone + "' cannot be parsed as a valid zone ID");
      return Optional.empty();
    }

View on GitHub (pinned to 184c821202)

Solutions

  1. Omit the branch parameter when searching issues fixed by a pull request.
  2. Set branch to the pull request's actual base (merge) branch, viewable in the SCM PR details.
  3. Re-target the pull request to the expected branch if the intent is to query against it.

Example fix

// before
searchRequest.fixedInPullRequest("PR-12").branch("main"); // PR targets develop
// after
searchRequest.fixedInPullRequest("PR-12").branch("develop");
Defensive patterns

Strategy: validation

Validate before calling

BranchDto pr = branchDao.selectByPullRequestKey(dbSession, uuid, prKey).orElseThrow();
BranchDto target = branchDao.selectByBranchKey(dbSession, uuid, branch).orElseThrow();
if (!target.getUuid().equals(pr.getMergeBranchUuid())) { /* wrong base branch — omit or fix branch param */ }

Try / catch

try { search(req); } catch (IllegalArgumentException e) { if (e.getMessage().contains("does not target branch")) { /* retry without the branch param */ } }

Prevention

When it happens

Trigger: Calling issue search with fixedInPullRequest=PR-12 and branch=main while PR-12 was opened against a different branch (e.g. develop); passing a branch name that exists but is not the PR's base branch.

Common situations: Dashboards hard-coding branch=main while PRs target feature branches; renamed or re-targeted pull requests in the SCM after a cached query was saved; copy-pasted queries across projects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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