SonarSource/sonarqube · error · IllegalArgumentException

The BitBucket project, in which the repository

Error message

The BitBucket project, in which the repository %s is located, is mandatory

What it means

BitbucketServerProjectCreator.getBitbucketProjectOrThrow() requires devOpsProjectDescriptor.projectIdentifier() (the Bitbucket project key) to be non-null before creating/importing the repository. When the descriptor was built without a project key, it throws IllegalArgumentException naming the repository identifier.

Solutions

  1. Pass the Bitbucket project key explicitly in the create/bind request alongside the repository
  2. Derive the project from the full repository URL (https://bitbucket.example.com/projects/<PROJ>/repos/<repo>) instead of just the repo name
  3. Fix the code constructing DevOpsProjectDescriptor to populate projectIdentifier before calling the creator
  4. Validate inputs client-side before submitting the descriptor

Example fix

// before
new DevOpsProjectDescriptor(..., projectIdentifier=null, repositoryIdentifier="my-repo")
// after
new DevOpsProjectDescriptor(..., projectIdentifier="PROJ", repositoryIdentifier="my-repo")
Defensive patterns

Strategy: validation

Validate before calling

// require both project key and repo before invoking the creator
if (!descriptor.projectIdentifier()) {
  throw new Error('Bitbucket project key is required along with repository');
}
const m = /\/projects\/([^/]+)\/repos\/([^/]+)/.exec(repoUrl);
const projectKey = m?.[1], repository = m?.[2];

Type guard

// Kotlin/Java-style null guard
fun hasProject(d: DevOpsProjectDescriptor) = !d.projectIdentifier().isNullOrEmpty()

Try / catch

try {
  creator.create(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("is mandatory")) {
    // supply the Bitbucket project key and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking Bitbucket Server project creation/binding with a DevOpsProjectDescriptor whose projectIdentifier is null — e.g. request parameters include repository but omit the Bitbucket project, or the descriptor was constructed programmatically without it.

Common situations: API calls to create the ALM binding omitting the 'project' parameter; automation scripts parsing only repo slug from a Bitbucket URL and dropping the project part.

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/43a2cc80d6f5a079. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/bitbucketserver/BitbucketServerProjectCreator.java:111

    ComponentCreationData componentCreationData = projectCreator.getOrCreateProject(dbSession, request);
    ProjectDto projectDto = Optional.ofNullable(componentCreationData.projectDto()).orElseThrow();
    createProjectAlmSettingDto(dbSession, repository, projectDto, almSettingDto, monorepo);

    return componentCreationData;
  }

  private String findPersonalAccessTokenOrThrow(DbSession dbSession) {
    String userUuid = requireNonNull(userSession.getUuid(), "User UUID cannot be null.");
    Optional<AlmPatDto> almPatDto = dbClient.almPatDao().selectByUserAndAlmSetting(dbSession, userUuid, almSettingDto);

    return almPatDto.map(AlmPatDto::getPersonalAccessToken)
      .orElseThrow(() -> new IllegalArgumentException(format("personal access token for '%s' is missing", almSettingDto.getKey())));
  }

  private String getBitbucketProjectOrThrow() {
    if (devOpsProjectDescriptor.projectIdentifier() == null) {
      throw new IllegalArgumentException(String.format("The BitBucket project, in which the repository %s is located, is mandatory",
        devOpsProjectDescriptor.repositoryIdentifier()));
    }
    return devOpsProjectDescriptor.projectIdentifier();
  }

  private String getDefaultBranchName(String url, String pat, String project, String repo) {
    BranchesList branches = bitbucketServerRestClient.getBranches(url, pat, project, repo);
    Optional<Branch> defaultBranch = branches.findDefaultBranch();
    return defaultBranch.map(Branch::getName).orElse(null);
  }

  private String getProjectKey(@Nullable String projectKey, Repository repo) {
    return Optional.ofNullable(projectKey).orElseGet(() -> projectKeyGenerator.generateUniqueProjectKey(repo.getProject().getKey(), repo.getSlug()));
  }

  private static String getProjectName(@Nullable String projectName, Repository repository) {
    return Optional.ofNullable(projectName).orElse(repository.getName());
  }

View on GitHub (pinned to 184c821202)