SonarSource/sonarqube · error · NotFoundException

Component '%s' of pull request '%s' not found

Error message

Component '%s' of pull request '%s' not found

What it means

NotFoundException thrown by ComponentFinder.getByKeyAndPullRequest when no enabled component DTO exists in the DB for the given component key combined with the given pull request key. It fires when API callers reference a component (file/module/directory) that either does not exist within that pull request's branch scope or has been disabled; it is a normal 404-style guard, not a corruption signal.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java:262

      .stream()
      .map(ComponentType::getQualifier)
      .collect(Collectors.toSet());
  }

  public ComponentDto getByKeyAndBranch(DbSession dbSession, String key, String branch) {
    Optional<ComponentDto> componentDto = dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);
    if (componentDto.isPresent() && componentDto.get().isEnabled()) {
      return componentDto.get();
    }
    throw new NotFoundException(format("Component '%s' on branch '%s' not found", key, branch));
  }

  public ComponentDto getByKeyAndPullRequest(DbSession dbSession, String key, String pullRequest) {
    Optional<ComponentDto> componentDto = dbClient.componentDao().selectByKeyAndPullRequest(dbSession, key, pullRequest);
    if (componentDto.isPresent() && componentDto.get().isEnabled()) {
      return componentDto.get();
    }
    throw new NotFoundException(format("Component '%s' of pull request '%s' not found", key, pullRequest));
  }

  public ComponentDto getByKeyAndOptionalBranchOrPullRequest(DbSession dbSession, String key, @Nullable String branch, @Nullable String pullRequest) {
    checkArgument(branch == null || pullRequest == null, "Either branch or pull request can be provided, not both");
    if (branch != null) {
      return getByKeyAndBranch(dbSession, key, branch);
    } else if (pullRequest != null) {
      return getByKeyAndPullRequest(dbSession, key, pullRequest);
    }
    return getByKey(dbSession, key);
  }

  public Optional<ComponentDto> getOptionalByKeyAndOptionalBranchOrPullRequest(DbSession dbSession, String key, @Nullable String branch, @Nullable String pullRequest) {
    checkArgument(branch == null || pullRequest == null, "Either branch or pull request can be provided, not both");
    if (branch != null) {
      return dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);
    } else if (pullRequest != null) {
      return dbClient.componentDao().selectByKeyAndPullRequest(dbSession, key, pullRequest);

View on GitHub (pinned to 184c821202)

Solutions

  1. List valid pull requests via api/project_pull_requests/list and use the exact key
  2. Re-run analysis on the open PR if its data was purged
  3. Verify the component key exists (api/components/search with pullRequest param)
  4. If the PR is closed, query the target branch instead

Example fix

// before
GET /api/measures/component?component=foo&pullRequest=123
// after
GET /api/project_pull_requests/list?project=foo  // key is e.g. 'PR-123' or branch name
GET /api/measures/component?component=foo&pullRequest=PR-123
Defensive patterns

Strategy: validation

Validate before calling

const prs = await api.pullRequests.list({ project: key });
if (!prs.some(p => p.key === prKey)) {
  throw new Error(`pull request '${prKey}' not found for ${key}`);
}

Try / catch

try {
  return await api.components.show({ component: key, pullRequest: pr });
} catch (e) {
  if (e.status === 404 && /of pull request .* not found/.test(e.message)) {
    return null; // PR likely closed/purged — fall back to target branch
  }
  throw e;
}

Prevention

When it happens

Trigger: api call with component=<key>&pullRequest=<pr> where the PR was deleted, the PR key is wrong, or the component doesn't exist in the PR's analysis.

Common situations: PR closed/deleted in the SCM so SonarQube purged the PR data; using the PR number instead of the branch/PR key SonarQube stored; typos or case mismatch in the PR key.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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