{"record":{"id":"92b619e8ffb0290c","repo":"SonarSource/sonarqube","slug":"cannot-mint-a-gitlab-access-token-unknown-project","errorCode":null,"errorMessage":"Cannot mint a GitLab access token: unknown project '{}'","messagePattern":"Cannot mint a GitLab access token: unknown project '(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/gitlab/GitlabScmAccessTokenProvider.java","lineNumber":98,"sourceCode":"    .build();\n  private final Striped<Lock> tokenRefreshLocks = Striped.lazyWeakLock(128);\n\n  public GitlabScmAccessTokenProvider(DbClient dbClient, GitlabGlobalSettingsValidator gitlabGlobalSettingsValidator,\n    GitlabApplicationClient gitlabApplicationClient, Settings settings) {\n    this.dbClient = dbClient;\n    this.gitlabGlobalSettingsValidator = gitlabGlobalSettingsValidator;\n    this.gitlabApplicationClient = gitlabApplicationClient;\n    this.encryption = settings.getEncryption();\n  }\n\n  @Override\n  public Optional<ScmAccessToken> mint(String projectKey) {\n    String safeProjectKey = sanitizeForLog(projectKey);\n    TokenMintRequest request;\n    try (DbSession dbSession = dbClient.openSession(false)) {\n      Optional<ProjectDto> project = dbClient.projectDao().selectProjectByKey(dbSession, projectKey);\n      if (project.isEmpty()) {\n        LOG.warn(\"Cannot mint a GitLab access token: unknown project '{}'\", safeProjectKey);\n        return Optional.empty();\n      }\n      Optional<ProjectAlmSettingDto> projectAlmSetting = dbClient.projectAlmSettingDao().selectByProject(dbSession, project.get());\n      if (projectAlmSetting.isEmpty()) {\n        LOG.warn(\"Cannot mint a GitLab access token: project '{}' is not bound to any DevOps Platform\", safeProjectKey);\n        return Optional.empty();\n      }\n      Optional<AlmSettingDto> almSetting = dbClient.almSettingDao().selectByUuid(dbSession, projectAlmSetting.get().getAlmSettingUuid());\n      if (almSetting.isEmpty() || almSetting.get().getAlm() != ALM.GITLAB) {\n        return Optional.empty();\n      }\n      Long gitlabProjectId = parseGitlabProjectId(projectAlmSetting.get().getAlmRepo(), safeProjectKey);\n      if (gitlabProjectId == null) {\n        return Optional.empty();\n      }\n      request = new TokenMintRequest(new TokenCacheKey(requireNonNull(project.get().getUuid(), \"Project UUID cannot be null\"),\n        requireNonNull(almSetting.get().getUuid(), \"ALM setting UUID cannot be null\"), gitlabProjectId, almSetting.get().getUpdatedAt()), safeProjectKey,\n        almSetting.get());","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/gitlab/GitlabScmAccessTokenProvider.java#L80-L116","documentation":"GitlabScmAccessTokenProvider.mint() looks up the project by its SonarQube key before requesting a GitLab personal access token. If no ProjectDto exists for the given key in the database, it logs this warning and returns Optional.empty() instead of a token. It is a lookup failure, not a crash: the caller receives an empty Optional.","triggerScenarios":"Calling mint(projectKey) with a project key that does not exist in SonarQube (deleted project, typo in key, wrong branch/monorepo key casing).","commonSituations":"CI pipelines configured with a stale project key after the project was deleted or its key was renamed; provisioning scripts that mint tokens before the project import finishes; typos in ALM-bound project keys.","solutions":["Verify the project key exists (Projects administration page or GET api/projects/show?key=...) and use the exact key in the mint call.","If the project was deleted, recreate/import it and rebind the DevOps platform before minting.","If the key was renamed, update the caller (CI job, script, provisioning config) with the new key.","Handle Optional.empty() from mint() gracefully and surface a clear message instead of retrying."],"exampleFix":"// before\nOptional<ScmAccessToken> token = provider.mint(\"com.example.app_old\");\n// after\nOptional<ProjectDto> project = dbClient.projectDao().selectProjectByKey(db, actualKey);\nif (project.isPresent()) {\n  Optional<ScmAccessToken> token = provider.mint(actualKey);\n}","handlingStrategy":"validation","validationCode":"// Java\ndbClient.projectDao().selectProjectByKey(dbSession, projectKey)\n  .orElseThrow(() -> new IllegalStateException(\"Unknown SonarQube project key: \" + projectKey));\n// then call mint(projectKey)","typeGuard":"boolean isKnownProject(DbSession db, String key) {\n  return dbClient.projectDao().selectProjectByKey(db, key).isPresent();\n}","tryCatchPattern":null,"preventionTips":["Resolve the project key via api/projects/search before minting.","Keep project keys in one config source of truth shared with CI.","Handle Optional.empty() from mint() explicitly with a clear log.","Re-check keys after project renames or deletions."],"tags":["gitlab","project-lookup","sonarqube","token-minting"],"backgroundTag":"record-not-found","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}