{"record":{"id":"128b7b8ac424bf0d","repo":"SonarSource/sonarqube","slug":"component-s-of-pull-request-s-not-found","errorCode":null,"errorMessage":"Component '%s' of pull request '%s' not found","messagePattern":"Component '(.+?)' of pull request '(.+?)' not found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java","lineNumber":262,"sourceCode":"      .stream()\n      .map(ComponentType::getQualifier)\n      .collect(Collectors.toSet());\n  }\n\n  public ComponentDto getByKeyAndBranch(DbSession dbSession, String key, String branch) {\n    Optional<ComponentDto> componentDto = dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);\n    if (componentDto.isPresent() && componentDto.get().isEnabled()) {\n      return componentDto.get();\n    }\n    throw new NotFoundException(format(\"Component '%s' on branch '%s' not found\", key, branch));\n  }\n\n  public ComponentDto getByKeyAndPullRequest(DbSession dbSession, String key, String pullRequest) {\n    Optional<ComponentDto> componentDto = dbClient.componentDao().selectByKeyAndPullRequest(dbSession, key, pullRequest);\n    if (componentDto.isPresent() && componentDto.get().isEnabled()) {\n      return componentDto.get();\n    }\n    throw new NotFoundException(format(\"Component '%s' of pull request '%s' not found\", key, pullRequest));\n  }\n\n  public ComponentDto getByKeyAndOptionalBranchOrPullRequest(DbSession dbSession, String key, @Nullable String branch, @Nullable String pullRequest) {\n    checkArgument(branch == null || pullRequest == null, \"Either branch or pull request can be provided, not both\");\n    if (branch != null) {\n      return getByKeyAndBranch(dbSession, key, branch);\n    } else if (pullRequest != null) {\n      return getByKeyAndPullRequest(dbSession, key, pullRequest);\n    }\n    return getByKey(dbSession, key);\n  }\n\n  public Optional<ComponentDto> getOptionalByKeyAndOptionalBranchOrPullRequest(DbSession dbSession, String key, @Nullable String branch, @Nullable String pullRequest) {\n    checkArgument(branch == null || pullRequest == null, \"Either branch or pull request can be provided, not both\");\n    if (branch != null) {\n      return dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);\n    } else if (pullRequest != null) {\n      return dbClient.componentDao().selectByKeyAndPullRequest(dbSession, key, pullRequest);","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java#L244-L280","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["List valid pull requests via api/project_pull_requests/list and use the exact key","Re-run analysis on the open PR if its data was purged","Verify the component key exists (api/components/search with pullRequest param)","If the PR is closed, query the target branch instead"],"exampleFix":"// before\nGET /api/measures/component?component=foo&pullRequest=123\n// after\nGET /api/project_pull_requests/list?project=foo  // key is e.g. 'PR-123' or branch name\nGET /api/measures/component?component=foo&pullRequest=PR-123","handlingStrategy":"validation","validationCode":"const prs = await api.pullRequests.list({ project: key });\nif (!prs.some(p => p.key === prKey)) {\n  throw new Error(`pull request '${prKey}' not found for ${key}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await api.components.show({ component: key, pullRequest: pr });\n} catch (e) {\n  if (e.status === 404 && /of pull request .* not found/.test(e.message)) {\n    return null; // PR likely closed/purged — fall back to target branch\n  }\n  throw e;\n}","preventionTips":["Get exact PR keys from api/project_pull_requests/list instead of SCM PR numbers","Skip closed/merged PRs in CI jobs (use pullRequest.value != closed)","Fallback to the target branch when PR data is purged","Re-trigger analysis for reopened PRs"],"tags":["java","components","pull-requests","not-found"],"backgroundTag":"record-not-found","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"}