{"record":{"id":"16d68f6a13f3ac6d","repo":"SonarSource/sonarqube","slug":"if-branch-key-is-specified-project-key-needs-to-b-16d68f","errorCode":null,"errorMessage":"If branch key is specified, project key needs to be specified too","messagePattern":"If branch key is specified, project key needs to be specified too","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java","lineNumber":93,"sourceCode":"        \"<li>'Administer System' to change the global setting</li>\" +\n        \"<li>'Administer' rights for a specified component</li>\" +\n        \"</ul>\")\n      .setSince(\"8.0\")\n      .setHandler(this);\n\n    action.createParam(PROJECT)\n      .setDescription(\"Project key\");\n    action.createParam(BRANCH)\n      .setDescription(\"Branch key\");\n  }\n\n  @Override\n  public void handle(Request request, Response response) throws Exception {\n    String projectKey = request.getParam(PROJECT).emptyAsNull().or(() -> null);\n    String branchKey = request.getParam(BRANCH).emptyAsNull().or(() -> null);\n\n    if (projectKey == null && branchKey != null) {\n      throw new IllegalArgumentException(\"If branch key is specified, project key needs to be specified too\");\n    }\n\n    try (DbSession dbSession = dbClient.openSession(false)) {\n      String projectUuid = null;\n      String branchUuid = null;\n\n      // in CE set main branch value instead of project value\n      boolean isCommunityEdition = editionProvider.get().filter(t -> t == EditionProvider.Edition.COMMUNITY).isPresent();\n\n      if (projectKey != null) {\n        ProjectDto project = getProject(dbSession, projectKey);\n        userSession.checkEntityPermission(ProjectPermission.ADMIN, project);\n        projectUuid = project.getUuid();\n\n        if (branchKey != null) {\n          branchUuid = getBranch(dbSession, project, branchKey).getUuid();\n        } else if (isCommunityEdition) {\n          branchUuid = getMainBranch(dbSession, project).getUuid();","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java#L75-L111","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the project=<projectKey> parameter to the api/new_code_periods/unset request whenever branch is specified","If you meant to unset the project-level definition, remove the branch parameter entirely","To unset the instance-level (global) definition, send neither project nor branch"],"exampleFix":"// before\ncurl -u token: -X POST 'https://sonar.example.com/api/new_code_periods/unset?branch=feature%2Fx'\n\n// after\ncurl -u token: -X POST 'https://sonar.example.com/api/new_code_periods/unset?project=my_project&branch=feature%2Fx'","handlingStrategy":"validation","validationCode":"if (branchKey && !projectKey) { throw new Error('branch requires project key'); }\nawait unsetNewCodePeriod({ project: projectKey, branch: branchKey });","typeGuard":"function canUnsetBranch(params) { return !(params.branch != null && params.project == null); }","tryCatchPattern":"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; } }","preventionTips":["Always send project together with branch for new_code_periods endpoints","Validate query params before building the request URL","Use the official WS client wrappers that enforce parameter pairs"],"tags":["webapi","new-code-period","missing-parameter","validation"],"backgroundTag":"missing-required-argument","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"}