SonarSource/sonarqube · error · NotFoundException

Project '%s' not found

Error message

Project '%s' not found

What it means

ComponentFinder.getProjectByKeyAndPermission looks up a project by key and then checks the user's permission. Both 'project does not exist' and 'you lack the given ProjectPermission' raise the same NotFoundException 'Project <key> not found' — it deliberately does not reveal whether the project exists.

Source

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

  public EntityDto getEntityByKey(DbSession dbSession, String entityKey) {
    return dbClient.entityDao().selectByKey(dbSession, entityKey)
      .orElseThrow(() -> new NotFoundException(String.format(LABEL_ENTITY_NOT_FOUND, entityKey)));
  }

  public EntityDto getEntityByUuid(DbSession dbSession, String entityUuid) {
    return dbClient.entityDao().selectByUuid(dbSession, entityUuid)
      .orElseThrow(() -> new NotFoundException(String.format(LABEL_ENTITY_NOT_FOUND, entityUuid)));
  }

  public ProjectDto getProjectByKey(DbSession dbSession, String projectKey) {
    return dbClient.projectDao().selectProjectByKey(dbSession, projectKey)
      .orElseThrow(() -> new NotFoundException(String.format(LABEL_PROJECT_NOT_FOUND, projectKey)));
  }

  public ProjectDto getProjectByKeyAndPermission(DbSession dbSession, String projectKey, UserSession userSession, ProjectPermission permission) {
    ProjectDto project = getProjectByKey(dbSession, projectKey);
    if (!userSession.hasEntityPermission(permission, project)) {
      throw new NotFoundException(String.format(LABEL_PROJECT_NOT_FOUND, projectKey));
    }
    return project;
  }

  public ProjectDto getApplicationByKey(DbSession dbSession, String applicationKey) {
    return dbClient.projectDao().selectApplicationByKey(dbSession, applicationKey)
      .orElseThrow(() -> new NotFoundException(String.format("Application '%s' not found", applicationKey)));
  }

  public ProjectDto getProjectOrApplicationByKey(DbSession dbSession, String projectKey) {
    return dbClient.projectDao().selectProjectOrAppByKey(dbSession, projectKey)
      .orElseThrow(() -> new NotFoundException(String.format(LABEL_PROJECT_NOT_FOUND, projectKey)));
  }

  public ProjectDto getProjectByUuid(DbSession dbSession, String projectUuid) {
    return dbClient.projectDao().selectByUuid(dbSession, projectUuid)
      .filter(p -> ComponentQualifiers.PROJECT.equals(p.getQualifier()))
      .orElseThrow(() -> new NotFoundException(String.format(LABEL_PROJECT_NOT_FOUND, projectUuid)));

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the project key exists via api/projects/search and matches exactly (case-sensitive)
  2. Check the authenticated user/token has the required permission (api/permissions) or use an admin token
  3. Confirm the project was not renamed/deleted; recreate or restore it if needed
  4. Pass the correct organization parameter when using SonarCloud

Example fix

// before
GET /api/projects/delete?project=my-projcet
// after
GET /api/projects/search?q=my-project  // confirm exact key first
GET /api/projects/delete?project=my-project
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm existence AND permission before the destructive call
const res = await api.projects.search({ q: key });
const project = res.components.find(p => p.key === key);
if (!project) throw new Error(`project ${key} not found or not visible to this token`);

Try / catch

try {
  await api.projects.delete({ project: key });
} catch (e) {
  if (e.status === 404 && /not found/.test(e.message)) {
    // ambiguous: missing project OR insufficient permission
    throw new Error(`Project '${key}' not found, or the token lacks the required permission`);
  }
  throw e;
}

Prevention

When it happens

Trigger: api call with a wrong project key, or a valid key where the current user lacks the required permission (e.g. admin, scan).

Common situations: Typo'd project keys; token of a user without project permissions; project deleted or key changed; using org-scoped keys without the organization parameter.

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