SonarSource/sonarqube · error · NotFoundException

Issue with key '%s' does not exist

Error message

Issue with key '%s' does not exist

What it means

Thrown by IssueFinder.getByKey when no issue exists for the given key, or when the key actually refers to a SECURITY_HOTSPOT. Hotspots are deliberately hidden from the issue APIs, producing the same NotFound message to avoid distinguishing the two cases.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueFinder.java:49

import static java.util.Objects.requireNonNull;
import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT;

public class IssueFinder {

  private final DbClient dbClient;
  private final UserSession userSession;

  public IssueFinder(DbClient dbClient, UserSession userSession) {
    this.dbClient = dbClient;
    this.userSession = userSession;
  }

  public IssueDto getByKey(DbSession session, String issueKey) {
    IssueDto issue = dbClient.issueDao().selectByKey(session, issueKey).orElseThrow(() -> new NotFoundException(format("Issue with key '%s' does not exist", issueKey)));

    RuleType ruleType = RuleType.valueOfNullable(issue.getType());
    if (SECURITY_HOTSPOT.equals(ruleType)) {
      throw new NotFoundException(format("Issue with key '%s' does not exist", issueKey));
    }

    userSession.checkComponentUuidPermission(ProjectPermission.USER, requireNonNull(issue.getProjectUuid()));
    return issue;
  }

}

View on GitHub (pinned to 184c821202)

Solutions

  1. Re-fetch the issue with GET api/issues/search to get a current, valid key
  2. If it is a hotspot, use api/hotspots/show and hotspot endpoints instead
  3. Refresh any cached issue keys after each analysis
  4. Verify the issue still exists before performing chained operations in automation

Example fix

// before
const issue = issues[0].key; // from an old scan
await post('/api/issues/add_comment', {issue, comment: 'x'});
// after
const {issues} = await get('/api/issues/search', {componentKeys: 'my_project', resolved: 'false'});
if (issues.length) await post('/api/issues/add_comment', {issue: issues[0].key, comment: 'x'});
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await searchIssues({issueKeys: [key]});
if (!res.issues.length) throw new Error('issue not found or is a hotspot');

Try / catch

try { await get('/api/issues/show', {key}); } catch (e) { if (e.status === 404) { /* key deleted or is a hotspot: refetch or use /api/hotspots/show */ } else throw e; }

Prevention

When it happens

Trigger: Calling api/issues/* endpoints (show, add_comment, transition, etc.) with an issue key that was deleted (bulk change, project re-scan removing issues), or with a hotspot key which is not an issue.

Common situations: Stale issue keys cached in CI dashboards after a full scan closed the issues; passing a hotspot key from api/hotspots/search into issue APIs; typos or truncated keys; issues purged when the project was re-analyzed with different rules.

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/af7ac3487cf16068. Report an issue: GitHub.