SonarSource/sonarqube · error · NotFoundException

%s key '%s' not found

Error message

%s key '%s' not found

What it means

checkComponent validates an Optional<ComponentDto> and throws NotFoundException with the caller-supplied message pattern ('%s key '%s' not found', e.g. 'Project key 'x' not found') when the component is missing, disabled, or does not live on a main branch. getByKey and getByUuidFromMainBranch route through it.

Source

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

  private ComponentDto getByKey(DbSession dbSession, String key, String label) {
    return checkComponent(dbSession, dbClient.componentDao().selectByKey(dbSession, key), "%s key '%s' not found", label, key);
  }

  public ComponentDto getByUuidFromMainBranch(DbSession dbSession, String uuid) {
    return getByUuidFromMainBranch(dbSession, uuid, LABEL_COMPONENT);
  }

  private ComponentDto getByUuidFromMainBranch(DbSession dbSession, String uuid, String label) {
    return checkComponent(dbSession, dbClient.componentDao().selectByUuid(dbSession, uuid), "%s id '%s' not found", label, uuid);
  }

  private ComponentDto checkComponent(DbSession session, Optional<ComponentDto> componentDto, String message, Object... messageArguments) {
    if (componentDto.isPresent() && componentDto.get().isEnabled()) {
      if (dbClient.branchDao().selectByUuid(session, componentDto.get().branchUuid()).map(BranchDto::isMain).orElse(true)) {
        return componentDto.get();
      }
    }
    throw new NotFoundException(format(message, messageArguments));
  }

  public ComponentDto getRootComponentByUuidOrKey(DbSession dbSession, @Nullable String projectUuid, @Nullable String projectKey) {
    ComponentDto project;
    if (projectUuid != null) {
      project = getByUuidFromMainBranch(dbSession, projectUuid, LABEL_PROJECT);
    } else {
      project = getByKey(dbSession, projectKey, LABEL_PROJECT);
    }
    checkIsProject(project);

    return project;
  }

  private ComponentDto checkIsProject(ComponentDto component) {
    Set<String> rootQualifiers = getRootQualifiers(componentTypes);

    checkRequest(component.scope().equals(ComponentScopes.PROJECT) && rootQualifiers.contains(component.qualifier()),

View on GitHub (pinned to 184c821202)

Solutions

  1. Use the project key instead of a stored UUID, or re-resolve the UUID from api/components/search
  2. Confirm the UUID belongs to the main branch component (branchUuid maps to a main BranchDto)
  3. Re-enable or recreate the component if it was disabled/deleted
  4. Refresh any cached component references after project key changes or deletions

Example fix

// before
client.components.show({ component: staleUuid })
// after
const search = await client.components.searchProjects({ q: 'my-project' });
const key = search.components[0].key;
await client.components.show({ component: key });
Defensive patterns

Strategy: validation

Validate before calling

// re-resolve the component key instead of a stored main-branch uuid
const res = await api.components.searchProjects({ q: name });
const c = res.components.find(p => p.key === name);
if (!c || c.enabled === false) throw new Error(`component '${name}' missing or disabled`);

Try / catch

try {
  const comp = await api.components.show({ component: idOrKey });
} catch (e) {
  if (e.status === 404 && /not found/.test(e.message)) {
    // treat as: deleted, disabled, or non-main-branch uuid — re-resolve by key
    return resolveComponentByKey(name);
  }
  throw e;
}

Prevention

When it happens

Trigger: Lookup by key/uuid where the component row is absent, the component is disabled (deleted flag), or its branch is not the main branch (e.g. UUID of a non-main branch component passed to getByUuidFromMainBranch).

Common situations: Using a branch component's UUID in APIs that expect main-branch components; referencing a deleted/disabled project; stale cached UUIDs after re-analysis.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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