SonarSource/sonarqube · warning
Failed to persist resolved url/repoId for DevOps Platform bi
Error message
Failed to persist resolved url/repoId for DevOps Platform binding '{}': {} ({}) What it means
This warning is logged by ProjectBindingsServiceServerImpl.persist when updating the resolved url and repoId of a DevOps Platform binding in the database throws. The session is explicitly rolled back (to avoid a poisoned PostgreSQL transaction) and only a sanitized message plus the exception class name is logged, because JDBC drivers may embed ALM-originated bind values in violation messages.
Source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ProjectBindingsServiceServerImpl.java:235
return new LiveResolution(storedUrl, storedRepoId);
}
LiveResolution resolved = resolveLive(almSetting, projectAlmSetting, bitbucketCloudTokenCache);
if (isNotBlank(resolved.url()) && isNotBlank(resolved.repoId())) {
persist(dbSession, projectAlmSetting, resolved);
}
return resolved;
}
private void persist(DbSession dbSession, ProjectAlmSettingDto projectAlmSetting, LiveResolution resolved) {
try {
dbClient.projectAlmSettingDao().updateUrlAndRepoId(dbSession, projectAlmSetting.getUuid(), resolved.url(), resolved.repoId());
dbSession.commit();
} catch (Exception e) {
// Not logging "e" directly: some JDBC drivers embed the failing bind value in a constraint/type-violation
// message, and resolved.url()/resolved.repoId() originate from ALM API responses — see the equivalent
// comment in resolveLive for why the raw throwable never reaches the logger in this class.
LOG.warn("Failed to persist resolved url/repoId for DevOps Platform binding '{}': {} ({})", projectAlmSetting.getUuid(),
sanitizeForLog(String.valueOf(e.getMessage())), e.getClass().getSimpleName());
// Rolls the session back to a usable state: on databases such as PostgreSQL, an aborted statement
// poisons the transaction until an explicit rollback, which would otherwise break every later read
// on this same session (e.g. the next binding in a searchProjectBindings batch).
dbSession.rollback();
}
}
private LiveResolution resolveLive(AlmSettingDto almSetting, ProjectAlmSettingDto projectAlmSetting, Map<String, String> bitbucketCloudTokenCache) {
try {
return switch (almSetting.getAlm()) {
case GITHUB -> resolveGithub(almSetting, projectAlmSetting);
case GITLAB -> resolveGitlab(almSetting, projectAlmSetting);
case AZURE_DEVOPS -> resolveAzure(almSetting, projectAlmSetting);
case BITBUCKET -> resolveBitbucketServer(almSetting, projectAlmSetting);
case BITBUCKET_CLOUD -> resolveBitbucketCloud(almSetting, projectAlmSetting, bitbucketCloudTokenCache);
};
} catch (Exception e) {View on GitHub (pinned to 184c821202)
Solutions
- Read the sanitized exception class and message from the log to distinguish connection errors from constraint violations
- Check the column lengths of PROJECT_ALM_SETTINGS.URL/REPO_ID against the values your ALM returns; shorten or alter the column if too small
- Verify database connectivity and re-run the binding search — persist is a cache refresh and will be retried on next resolution
- If on PostgreSQL, note the code already rolls back; ensure no manual code path keeps using the aborted session
Example fix
// before: value exceeds column ALTER TABLE project_alm_settings ALTER COLUMN url TYPE text; -- or fix data upstream // after: truncated/corrected binding persisted successfully
Defensive patterns
Strategy: retry
Validate before calling
// Before persist, sanity-check resolved values against DB limits
assert resolved.url() != null;
if (resolved.url().length() > MAX_URL_COLUMN) throw new IllegalStateException("Resolved URL exceeds column size: " + resolved.url().length()); Try / catch
// Pattern used by the code itself: rollback and move on
try { dao.updateUrlAndRepoId(session, uuid, url, repoId); session.commit(); }
catch (Exception e) { log.warn("persist failed: {} ({})", sanitize(e.getMessage()), e.getClass().getSimpleName()); session.rollback(); } Prevention
- Size URL/repoId columns generously (text) for ALM payloads
- Monitor DB connectivity and failover events during binding searches
- Re-run binding searches after transient DB errors — persist is idempotent cache refresh
- Keep SonarQube and DB schema versions aligned after upgrades
When it happens
Trigger: resolveUrlAndRepoId resolving a binding successfully, then projectAlmSettingDao().updateUrlAndRepoId failing: DB connection issues, constraint/type violation on URL or repoId columns (e.g. value too long), dead session, or unique-constraint problems.
Common situations: ALM API returned a URL longer than the column size; transient DB failover during a bindings search; concurrent updates to the same binding row; schema drift after upgrade.
Related errors
- Fail to connect to database
- Can not connect to database. Please check connectivity and s
- Can not get database connection
- Unsupported JDBC driver provider: %s
- Failed to construct GitHub repository URL for ALM setting '{
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/070bd6bf4e011639.
Report an issue: GitHub.