SonarSource/sonarqube · error · IllegalArgumentException

If branch key is specified, project key needs to be…

Error message

If branch key is specified, project key needs to be specified too

What it means

The api/new_code_periods/unset WebService endpoint requires that a branch key never appears without a project key. UnsetAction.handle parses both optional params and throws IllegalArgumentException immediately if BRANCH is set but PROJECT is not. This prevents ambiguous requests where a branch cannot be resolved without its parent project.

Solutions

  1. Add the project=<projectKey> parameter to the api/new_code_periods/unset request whenever branch is specified
  2. If you meant to unset the project-level definition, remove the branch parameter entirely
  3. To unset the instance-level (global) definition, send neither project nor branch

Example fix

// before
curl -u token: -X POST 'https://sonar.example.com/api/new_code_periods/unset?branch=feature%2Fx'

// after
curl -u token: -X POST 'https://sonar.example.com/api/new_code_periods/unset?project=my_project&branch=feature%2Fx'
Defensive patterns

Strategy: validation

Validate before calling

if (branchKey && !projectKey) { throw new Error('branch requires project key'); }
await unsetNewCodePeriod({ project: projectKey, branch: branchKey });

Type guard

function canUnsetBranch(params) { return !(params.branch != null && params.project == null); }

Try / catch

try { await api.unsetNcd({ project, branch }); } catch (e) { if (e.message.includes('project key needs to be specified')) { /* add project param and retry */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling POST api/new_code_periods/unset with branch=<branchKey> but omitting the project parameter. Any WS client (curl, SonarQube JS client, scanner integrations) hitting the unset endpoint with only a branch key.

Common situations: Scripts that unset new code definitions per-branch but forget the project key; templated API calls where the project variable resolves to empty and only the branch param is sent; copy-paste from branch-scoped examples that assumed a default project.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java:93

        "<li>'Administer System' to change the global setting</li>" +
        "<li>'Administer' rights for a specified component</li>" +
        "</ul>")
      .setSince("8.0")
      .setHandler(this);

    action.createParam(PROJECT)
      .setDescription("Project key");
    action.createParam(BRANCH)
      .setDescription("Branch key");
  }

  @Override
  public void handle(Request request, Response response) throws Exception {
    String projectKey = request.getParam(PROJECT).emptyAsNull().or(() -> null);
    String branchKey = request.getParam(BRANCH).emptyAsNull().or(() -> null);

    if (projectKey == null && branchKey != null) {
      throw new IllegalArgumentException("If branch key is specified, project key needs to be specified too");
    }

    try (DbSession dbSession = dbClient.openSession(false)) {
      String projectUuid = null;
      String branchUuid = null;

      // in CE set main branch value instead of project value
      boolean isCommunityEdition = editionProvider.get().filter(t -> t == EditionProvider.Edition.COMMUNITY).isPresent();

      if (projectKey != null) {
        ProjectDto project = getProject(dbSession, projectKey);
        userSession.checkEntityPermission(ProjectPermission.ADMIN, project);
        projectUuid = project.getUuid();

        if (branchKey != null) {
          branchUuid = getBranch(dbSession, project, branchKey).getUuid();
        } else if (isCommunityEdition) {
          branchUuid = getMainBranch(dbSession, project).getUuid();

View on GitHub (pinned to 184c821202)