{"record":{"id":"e2ae12bb456f1da9","repo":"SonarSource/sonarqube","slug":"cannot-provide-an-azure-devops-access-token-proje","errorCode":null,"errorMessage":"Cannot provide an Azure DevOps access token: project '{}' is not bound to any DevOps Platform","messagePattern":"Cannot provide an Azure DevOps 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/azuredevops/AzureDevOpsScmAccessTokenProvider.java","lineNumber":104,"sourceCode":"    // DbSession above — see GitlabScmAccessTokenProvider for the same rationale.\n    return resolvedAlmSetting.map(almSetting -> passThrough(safeProjectKey, almSetting));\n  }\n\n  /**\n   * Walks project -&gt; its DevOps Platform binding -&gt; the bound {@link AlmSettingDto}, short-circuiting\n   * to {@link Optional#empty()} (with a warning) at whichever step is missing, or once the binding\n   * turns out not to be Azure DevOps.\n   */\n  private Optional<AlmSettingDto> resolveAzureDevOpsAlmSetting(DbSession dbSession, String projectKey, String safeProjectKey) {\n    Optional<ProjectDto> project = dbClient.projectDao().selectProjectByKey(dbSession, projectKey);\n    if (project.isEmpty()) {\n      LOG.warn(\"Cannot provide an Azure DevOps access token: unknown project '{}'\", safeProjectKey);\n      return Optional.empty();\n    }\n\n    Optional<ProjectAlmSettingDto> projectAlmSetting = dbClient.projectAlmSettingDao().selectByProject(dbSession, project.get());\n    if (projectAlmSetting.isEmpty()) {\n      LOG.warn(\"Cannot provide an Azure DevOps access token: project '{}' is not bound to any DevOps Platform\", safeProjectKey);\n      return Optional.empty();\n    }\n\n    return dbClient.almSettingDao().selectByUuid(dbSession, projectAlmSetting.get().getAlmSettingUuid())\n      .filter(almSetting -> almSetting.getAlm() == ALM.AZURE_DEVOPS);\n  }\n\n  private ScmAccessToken passThrough(String safeProjectKey, AlmSettingDto almSetting) {\n    // AzureDevOpsValidator.validate() can fail with either IllegalArgumentException (bad config) or\n    // NullPointerException (missing URL/PAT via requireNonNull) — caught here as RuntimeException,\n    // rather than naming NullPointerException explicitly, to avoid catching it as a control-flow signal.\n    try {\n      azureDevOpsValidator.validate(almSetting);\n    } catch (RuntimeException e) {\n      throw new IllegalArgumentException(\n        format(\"Cannot provide an Azure DevOps access token for project '%s': invalid Azure DevOps configuration: %s\", safeProjectKey, e.getMessage()), e);\n    }\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/azuredevops/AzureDevOpsScmAccessTokenProvider.java#L86-L122","documentation":"AzureDevOpsScmAccessTokenProvider.resolveAzureDevOpsAlmSetting logs this warning and returns Optional.empty() when the project exists but projectAlmSettingDao.selectByProject finds no DevOps Platform binding for it. The project is not linked to any ALM binding, so no Azure DevOps access token can be minted. Like the other steps in mint(), this is an intentional soft-fail returning empty rather than throwing.","triggerScenarios":"Minting an Azure DevOps SCM access token for a projectKey that exists but has no entry in project_alm_settings (binding never created, or was deleted).","commonSituations":"Team created the SonarQube project manually instead of importing from Azure DevOps; the ALM binding was removed during cleanup; project imported under a different binding later unbound by an admin.","solutions":["Bind the project to Azure DevOps: Project Settings > DevOps Platform Integration, or POST api/alm_settings/set_azure_devops with almSetting and project keys.","Ensure an Azure DevOps ALM configuration exists at global level (api/alm_integrations/create_azure_devops) before binding.","If binding was accidental, recreate it and retry the token request.","In automation, check the binding first via api/alm_settings/get_binding?project=<key> and skip/repair accordingly."],"exampleFix":"// before: project 'my-app' has no DevOps Platform binding -> token request returns empty\n// after\ncurl -u token: -X POST \"$SQ_URL/api/alm_settings/set_azure_devops\" \\\n  -d \"project=my-app\" -d \"almSetting=ado-company\" -d \"repositoryName=org/repo\"","handlingStrategy":"validation","validationCode":"# Check binding before minting\nBINDING=$(curl -s -u \"$TOKEN:\" \"$SQ_URL/api/alm_settings/get_binding?project=$KEY\")\nif echo \"$BINDING\" | grep -q 'error'; then echo \"Project not bound to a DevOps Platform; bind first\" >&2; fi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Include the DevOps Platform binding step in every project provisioning script.","Treat an empty token response as 'binding missing' and route to remediation.","Audit bindings periodically with api/alm_settings/get_binding."],"tags":["azure-devops","missing-binding","alm-integration","configuration"],"backgroundTag":"missing-configuration","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"}