{"record":{"id":"52b6280950acac1a","repo":"SonarSource/sonarqube","slug":"cannot-mint-a-gitlab-access-token-project-is","errorCode":null,"errorMessage":"Cannot mint a GitLab access token: project '{}' is not bound to any DevOps Platform","messagePattern":"Cannot mint a GitLab access token: project '(.+?)' is not bound to any DevOps Platform","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":103,"sourceCode":"    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());\n    }\n\n    // GitLab API calls below are network I/O, deliberately made outside the DbSession above, so a\n    // pooled DB connection is not held for their duration.\n    return Optional.of(getOrCreateToken(request));","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/gitlab/GitlabScmAccessTokenProvider.java#L85-L121","documentation":"mint() found the project, but projectAlmSettingDao().selectByProject() returned nothing, meaning the project has no ALM/DevOps platform binding. GitLab token minting requires a bound GitLab project, so the method logs this warning and returns Optional.empty().","triggerScenarios":"Calling mint(projectKey) for a project that exists in SonarQube but was never bound to a DevOps platform setting (PROJECT_BINDINGS not configured), or whose binding was deleted.","commonSituations":"Manually created projects without DevOps platform integration; import/bind step skipped in provisioning; admin removed the ALM binding; project imported via another mechanism (e.g. generic import) losing the binding.","solutions":["Bind the project to a GitLab DevOps platform setting (Project Settings > DevOps Platform Integration, or api/alm_settings/set_gitlab).","Ensure the ALM setting itself exists and is of type GITLAB before binding.","Re-run project import (api/alm_settings/import_bindings) if the binding was lost during migration.","Handle the empty Optional as 'not integrated' rather than retrying mint."],"exampleFix":"// before\nprovider.mint(\"my.project\"); // project not bound -> empty\n// after\nalmSettingsService.setGitlabProjectSetting(db, \"my.project\", almSettingUuid, \"12345\");\nOptional<ScmAccessToken> token = provider.mint(\"my.project\");","handlingStrategy":"validation","validationCode":"// before minting, verify the ALM binding exists\nOptional<ProjectAlmSettingDto> binding =\n  dbClient.projectAlmSettingDao().selectByProject(dbSession, projectDto);\nif (binding.isEmpty()) { throw new IllegalStateException(\"Project not bound to a DevOps platform\"); }","typeGuard":"boolean isBoundToAlm(DbSession db, ProjectDto project) {\n  return dbClient.projectAlmSettingDao().selectByProject(db, project).isPresent();\n}","tryCatchPattern":null,"preventionTips":["Bind every provisioned project to a GitLab ALM setting as part of provisioning.","Run api/alm_settings/import_bindings after bulk imports.","Audit unbound projects periodically (api/projects + binding status).","Fail provisioning early when binding step is skipped."],"tags":["gitlab","alm-binding","sonarqube","token-minting"],"backgroundTag":"resource-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"}