SonarSource/sonarqube · error · IllegalStateException
No uuid found for Bitbucket Cloud repository
Error message
No uuid found for Bitbucket Cloud repository '%s'
What it means
SonarQube throws this when a Bitbucket Cloud repository response lacks a 'uuid' field. The uuid is stored as the external repository id in the project binding, so resolution cannot proceed without it. It indicates an unexpected/deficient API payload.
Solutions
- Verify GET /2.0/repositories/{workspace}/{repo} includes a uuid field for the repo
- Retry the binding resolution — the error can stem from a transient bad response
- Check any proxies or Bitbucket integrations that might alter response bodies
- Update SonarQube to a version compatible with the current Bitbucket Cloud API
Defensive patterns
Strategy: retry
Validate before calling
const res = await fetch(`https://api.bitbucket.org/2.0/repositories/${workspace}/${repo}`, { headers: { Authorization: `Bearer ${token}` } });
const data = await res.json();
if (!data.uuid) {
throw new Error(`Repo ${workspace}/${repo} response lacks uuid — check API version/proxies`);
} Type guard
function hasUuid(repo) {
return typeof repo?.uuid === 'string' && repo.uuid.length > 0;
} Try / catch
try {
resolution = resolveLive(almSetting, projectAlmSetting);
} catch (IllegalStateException e) {
if (e.getMessage().contains("No uuid found")) {
// transient/bad payload: retry once, then surface API-response diagnostics
resolution = retryResolveOnce(almSetting, projectAlmSetting);
} else { throw e; }
} Prevention
- Retry transient Bitbucket Cloud resolution failures before failing the binding
- Remove any proxies/interceptors that strip fields from Bitbucket API JSON
- Keep SonarQube updated for current Bitbucket Cloud API compatibility
- Spot-check that GET /2.0/repositories/{workspace}/{repo} includes uuid in your environment
When it happens
Trigger: resolveLive -> resolveBitbucketCloud gets a Repository whose getUuid() is null after getRepoWithAccessToken() succeeds — the html link exists but the uuid is absent from the API response.
Common situations: Bitbucket Cloud API changes or partial responses; proxy/gateway stripping fields; extremely old cached responses; repo metadata corruption on the Bitbucket side.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- No html link found for Bitbucket Cloud repository
- Cannot mint a GitLab access token: project
- Cannot mint a GitLab access token: project
- e.getMessage()
- Error returned by Bitbucket Cloud
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/0d11f8f50d36ddc0.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ProjectBindingsServiceServerImpl.java:336
return new LiveResolution(url, String.valueOf(repository.getId()));
}
private LiveResolution resolveBitbucketCloud(AlmSettingDto almSetting, ProjectAlmSettingDto projectAlmSetting, Map<String, String> tokenCache) {
String clientId = requireNonNull(almSetting.getClientId(), CLIENT_ID_CANNOT_BE_NULL);
String clientSecret = requireNonNull(almSetting.getDecryptedClientSecret(encryption), CLIENT_SECRET_CANNOT_BE_NULL);
String workspace = requireNonNull(almSetting.getAppId(), WORKSPACE_CANNOT_BE_NULL);
String almRepo = requireNonNull(projectAlmSetting.getAlmRepo(), ALM_REPO_CANNOT_BE_NULL);
// The OAuth token is workspace-wide, not per-repository: reuse it across every binding of this ALM setting
// resolved within the same request instead of minting a fresh one per binding.
String accessToken = tokenCache.computeIfAbsent(almSetting.getUuid(), uuid -> bitbucketCloudRestClient.createAccessToken(clientId, clientSecret));
org.sonar.alm.client.bitbucket.bitbucketcloud.Repository repository = bitbucketCloudRestClient.getRepoWithAccessToken(accessToken, workspace, almRepo);
String url = repository.getHtmlHref();
if (url == null) {
throw new IllegalStateException(format("No html link found for Bitbucket Cloud repository '%s'", sanitizeForLog(almRepo)));
}
String repoId = repository.getUuid();
if (repoId == null) {
throw new IllegalStateException(format("No uuid found for Bitbucket Cloud repository '%s'", sanitizeForLog(almRepo)));
}
return new LiveResolution(url, repoId);
}
/**
* GitHub's installation-token "repositories" scoping parameter expects the bare repository name
* (no {@code owner/} prefix), unlike {@code almRepo} which is stored as {@code owner/repo}.
*/
private static String bareRepositoryName(String almRepo) {
int lastSlash = almRepo.lastIndexOf('/');
return lastSlash < 0 ? almRepo : almRepo.substring(lastSlash + 1);
}
/**
* Strips CR/LF from ALM-supplied identifiers (repo/project keys, slugs) before they're embedded in an exception
* message that ends up in a log line — otherwise a crafted value could forge extra log entries (CWE-117). Only
* used for messages; the real, unsanitized value is always what's sent to the ALM REST clients.
*/View on GitHub (pinned to 184c821202)