SonarSource/sonarqube · error · IllegalArgumentException

GitLab project identifier must be a number, was '%s'

Error message

GitLab project identifier must be a number, was '%s'

What it means

GitlabDevOpsProjectCreationContextService.getGitlabProjectId() parses devOpsProjectDescriptor.repositoryIdentifier() with Long.parseLong to obtain the GitLab numeric project ID. If it is not a valid number, it throws IllegalArgumentException("GitLab project identifier must be a number, was '%s'").

Source

Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/gitlab/GitlabDevOpsProjectCreationContextService.java:79

    return DevOpsProjectCreationContext.builder()
      .name(gitlabProject.getName())
      .fullName(gitlabProject.getPathWithNamespace())
      .devOpsPlatformIdentifier(String.valueOf(gitlabProjectId))
      .url(gitlabProject.getWebUrl())
      .repoId(String.valueOf(gitlabProject.getId()))
      .isPublic(gitlabProject.getVisibility().equals("public"))
      .defaultBranchName(defaultBranchName)
      .almSettingDto(almSettingDto)
      .userSession(userSession)
      .build();

  }

  private static Long getGitlabProjectId(DevOpsProjectDescriptor devOpsProjectDescriptor) {
    try {
      return Long.parseLong(devOpsProjectDescriptor.repositoryIdentifier());
    } catch (NumberFormatException e) {
      throw new IllegalArgumentException(format("GitLab project identifier must be a number, was '%s'", devOpsProjectDescriptor.repositoryIdentifier()));
    }
  }

  private String findPersonalAccessTokenOrThrow(AlmSettingDto almSettingDto) {
    try (DbSession dbSession = dbClient.openSession(false)) {
      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 Project fetchGitlabProject(String gitlabUrl, String pat, Long gitlabProjectId) {
    try {
      return gitlabApplicationClient.getProject(
        gitlabUrl,
        pat,
        gitlabProjectId);

View on GitHub (pinned to 184c821202)

Solutions

  1. Enter GitLab's numeric project ID (visible under the project name on the project page / Settings > General) instead of the slug
  2. Fetch the ID programmatically: GET https://gitlab.example.com/api/v4/projects/<url-encoded-path> and use its 'id' field
  3. Trim whitespace and ensure the field contains only digits before submitting
  4. Fix calling code to pass repositoryIdentifier as the numeric ID, not the path

Example fix

// before
repositoryIdentifier: "my-group/my-project"
// after
repositoryIdentifier: "12345678"  // numeric GitLab project ID
Defensive patterns

Strategy: validation

Validate before calling

// resolve numeric GitLab project ID from a path/URL before submission
function gitlabProjectId(idOrPath) {
  if (/^\d+$/.test(String(idOrPath).trim())) return String(idOrPath).trim();
  throw new Error(`GitLab project identifier must be the numeric project ID, got '${idOrPath}'`);
}

Type guard

const isNumericId = (v) => typeof v === 'string' && /^\d+$/.test(v.trim());

Try / catch

try {
  createGitlabProject(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("GitLab project identifier must be a number")) {
    // resolve numeric ID via GET /api/v4/projects/<encoded-path> and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Creating/binding a GitLab DevOps project where the repository identifier supplied (the 'project id' field) is a non-numeric string — e.g. a repo path like 'group/project', a URL, or stray whitespace instead of GitLab's numeric project ID.

Common situations: Users pasting the GitLab repository URL or full name into the Project ID field; copy of the numeric project ID from the project's Settings > General page missed; automation scripts sending repo slugs instead of IDs.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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