{"record":{"id":"a04fb4377228279f","repo":"SonarSource/sonarqube","slug":"project-is-invalid","errorCode":null,"errorMessage":"Project is invalid","messagePattern":"Project is invalid","errorType":"exception","errorClass":"ProjectBadgesException","httpStatus":null,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/ProjectBadgesSupport.java","lineNumber":87,"sourceCode":"      .setRequired(true)\n      .setExampleValue(KEY_PROJECT_EXAMPLE_001);\n    action\n      .createParam(PARAM_TOKEN)\n      .setDescription(\n        \"Project badge token. Required for private projects or if the 'sonar.forceAuthentication' setting is enabled.\"\n      )\n      .setExampleValue(PROJECT_BADGE_TOKEN_EXAMPLE);\n  }\n\n  BranchDto getBranch(DbSession dbSession, Request request) {\n    try {\n      String branchName = request.param(PARAM_BRANCH);\n      ProjectDto project = getProject(dbSession, request);\n\n      BranchDto branch = componentFinder.getBranchOrPullRequest(dbSession, project, branchName, null);\n\n      if (!branch.getBranchType().equals(BRANCH)) {\n        throw generateInvalidProjectException();\n      }\n\n      return branch;\n    } catch (NotFoundException e) {\n      throw new NotFoundException(PROJECT_HAS_NOT_BEEN_FOUND);\n    }\n  }\n\n  public ProjectDto getProject(DbSession dbSession, Request request) {\n    String projectKey = request.mandatoryParam(PARAM_PROJECT);\n    return componentFinder.getProjectOrApplicationByKey(dbSession, projectKey);\n  }\n\n  private static ProjectBadgesException generateInvalidProjectException() {\n    return new ProjectBadgesException(\"Project is invalid\");\n  }\n\n  public void validateToken(Request request) {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/ProjectBadgesSupport.java#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a real branch name (e.g. 'main', 'master') in the branch parameter, not a pull-request key.","Verify the branch exists: GET /api/project_branches/list?project=KEY.","Run an analysis on the target branch so it exists in the DB.","If you need PR status, use /api/pull_requests or the PR decoration features instead of badges."],"exampleFix":"// before\nGET /api/project_badges/quality_gate?project=my_proj&branch=PR-123\n// after\nGET /api/project_badges/quality_gate?project=my_proj&branch=main","handlingStrategy":"validation","validationCode":"// shell: confirm the branch exists and is not a PR before fetching a badge\nBRANCHES=$(curl -s -u token: \"$SONAR/api/project_branches/list?project=$KEY\")\necho \"$BRANCHES\" | grep -q \"\\\"name\\\":\\s*\\\"$BRANCH\\\"\" || { echo \"branch not found\"; exit 1; }","typeGuard":null,"tryCatchPattern":"try {\n  badge = fetchBadge(project, branch);\n} catch (BadRequestException e) {\n  if (e.getMessage().contains(\"Project is invalid\")) {\n    // branch is a PR or missing: fall back to default branch\n    badge = fetchBadge(project, \"main\");\n  } else { throw e; }\n}","preventionTips":["Generate badge URLs from branch names, never PR keys.","List branches via /api/project_branches/list before embedding badge URLs.","Handle branch renames/deletions in CI badge generation."],"tags":["sonarqube","webapi","badges","branches"],"backgroundTag":"invalid-argument-value","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}