SonarSource/sonarqube · error · ProjectBadgesException

Project is invalid

Error message

Project is invalid

What it means

BadRequestException 'Project is invalid' from the badges web API when the requested branch exists but is a pull request rather than a regular branch (or when the project/branch lookup fails and the NotFoundException is rewrapped as 'Project has not been found'). Badge endpoints only render badges for real branches.

Solutions

  1. Pass a real branch name (e.g. 'main', 'master') in the branch parameter, not a pull-request key.
  2. Verify the branch exists: GET /api/project_branches/list?project=KEY.
  3. Run an analysis on the target branch so it exists in the DB.
  4. If you need PR status, use /api/pull_requests or the PR decoration features instead of badges.

Example fix

// before
GET /api/project_badges/quality_gate?project=my_proj&branch=PR-123
// after
GET /api/project_badges/quality_gate?project=my_proj&branch=main
Defensive patterns

Strategy: validation

Validate before calling

// shell: confirm the branch exists and is not a PR before fetching a badge
BRANCHES=$(curl -s -u token: "$SONAR/api/project_branches/list?project=$KEY")
echo "$BRANCHES" | grep -q "\"name\":\s*\"$BRANCH\"" || { echo "branch not found"; exit 1; }

Try / catch

try {
  badge = fetchBadge(project, branch);
} catch (BadRequestException e) {
  if (e.getMessage().contains("Project is invalid")) {
    // branch is a PR or missing: fall back to default branch
    badge = fetchBadge(project, "main");
  } else { throw e; }
}

Prevention

When it happens

Trigger: GET /api/project_badges/quality_gate (or measure) with PARAM_BRANCH set to a pull-request key or a non-BRANCH type entry; calling badges for a PR-based component; typo'd branch key falling into NotFoundException handling.

Common situations: CI badge URLs generated from PR numbers instead of branch names; branch renamed/deleted so lookup returns NotFound; querying badges for main branch before analysis created it.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/ProjectBadgesSupport.java:87

      .setRequired(true)
      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
    action
      .createParam(PARAM_TOKEN)
      .setDescription(
        "Project badge token. Required for private projects or if the 'sonar.forceAuthentication' setting is enabled."
      )
      .setExampleValue(PROJECT_BADGE_TOKEN_EXAMPLE);
  }

  BranchDto getBranch(DbSession dbSession, Request request) {
    try {
      String branchName = request.param(PARAM_BRANCH);
      ProjectDto project = getProject(dbSession, request);

      BranchDto branch = componentFinder.getBranchOrPullRequest(dbSession, project, branchName, null);

      if (!branch.getBranchType().equals(BRANCH)) {
        throw generateInvalidProjectException();
      }

      return branch;
    } catch (NotFoundException e) {
      throw new NotFoundException(PROJECT_HAS_NOT_BEEN_FOUND);
    }
  }

  public ProjectDto getProject(DbSession dbSession, Request request) {
    String projectKey = request.mandatoryParam(PARAM_PROJECT);
    return componentFinder.getProjectOrApplicationByKey(dbSession, projectKey);
  }

  private static ProjectBadgesException generateInvalidProjectException() {
    return new ProjectBadgesException("Project is invalid");
  }

  public void validateToken(Request request) {

View on GitHub (pinned to 184c821202)